merged tdb from ctdb bzr tree
[ira/wip.git] / source / lib / tdb / common / traverse.c
index fb2371d40396433b8166c6aeb9d55e598a89a9f0..2bde1270a078f2df05ddf235fb14cd6fd5218df0 100644 (file)
@@ -14,7 +14,7 @@
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
-   version 2 of the License, or (at your option) any later version.
+   version 3 of the License, or (at your option) any later version.
 
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -22,8 +22,7 @@
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "tdb_private.h"
@@ -205,12 +204,10 @@ int tdb_traverse_read(struct tdb_context *tdb,
 {
        struct tdb_traverse_lock tl = { NULL, 0, 0, F_RDLCK };
        int ret;
-       
+
        /* we need to get a read lock on the transaction lock here to
           cope with the lock ordering semantics of solaris10 */
-       if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_RDLCK, F_SETLKW, 0, 1) == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_traverse_read: failed to get transaction lock\n"));
-               tdb->ecode = TDB_ERR_LOCK;
+       if (tdb_transaction_lock(tdb, F_RDLCK)) {
                return -1;
        }
 
@@ -218,7 +215,7 @@ int tdb_traverse_read(struct tdb_context *tdb,
        ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
        tdb->traverse_read--;
 
-       tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
+       tdb_transaction_unlock(tdb);
 
        return ret;
 }
@@ -237,15 +234,15 @@ int tdb_traverse(struct tdb_context *tdb,
                return tdb_traverse_read(tdb, fn, private_data);
        }
        
-       if (tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_WRLCK, F_SETLKW, 0, 1) == -1) {
-               TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_traverse: failed to get transaction lock\n"));
-               tdb->ecode = TDB_ERR_LOCK;
+       if (tdb_transaction_lock(tdb, F_WRLCK)) {
                return -1;
        }
 
+       tdb->traverse_write++;
        ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
+       tdb->traverse_write--;
 
-       tdb->methods->tdb_brlock(tdb, TRANSACTION_LOCK, F_UNLCK, F_SETLKW, 0, 1);
+       tdb_transaction_unlock(tdb);
 
        return ret;
 }
@@ -263,12 +260,15 @@ TDB_DATA tdb_firstkey(struct tdb_context *tdb)
        tdb->travlocks.off = tdb->travlocks.hash = 0;
        tdb->travlocks.lock_rw = F_RDLCK;
 
+       /* Grab first record: locks chain and returned record. */
        if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0)
                return tdb_null;
        /* now read the key */
        key.dsize = rec.key_len;
        key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize);
-       if (tdb_unlock(tdb, BUCKET(tdb->travlocks.hash), F_WRLCK) != 0)
+
+       /* Unlock the hash chain of the record we just read. */
+       if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0)
                TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_firstkey: error occurred while tdb_unlocking!\n"));
        return key;
 }
@@ -276,14 +276,14 @@ TDB_DATA tdb_firstkey(struct tdb_context *tdb)
 /* find the next entry in the database, returning its key */
 TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey)
 {
-       u32 oldhash;
+       uint32_t oldhash;
        TDB_DATA key = tdb_null;
        struct list_struct rec;
        unsigned char *k = NULL;
 
        /* Is locked key the old key?  If so, traverse will be reliable. */
        if (tdb->travlocks.off) {
-               if (tdb_lock(tdb,tdb->travlocks.hash,F_WRLCK))
+               if (tdb_lock(tdb,tdb->travlocks.hash,tdb->travlocks.lock_rw))
                        return tdb_null;
                if (tdb_rec_read(tdb, tdb->travlocks.off, &rec) == -1
                    || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),
@@ -294,7 +294,7 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey)
                                SAFE_FREE(k);
                                return tdb_null;
                        }
-                       if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0) {
+                       if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0) {
                                SAFE_FREE(k);
                                return tdb_null;
                        }
@@ -306,7 +306,7 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey)
 
        if (!tdb->travlocks.off) {
                /* No previous element: do normal find, and lock record */
-               tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), F_WRLCK, &rec);
+               tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), tdb->travlocks.lock_rw, &rec);
                if (!tdb->travlocks.off)
                        return tdb_null;
                tdb->travlocks.hash = BUCKET(rec.full_hash);
@@ -324,11 +324,11 @@ TDB_DATA tdb_nextkey(struct tdb_context *tdb, TDB_DATA oldkey)
                key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec),
                                          key.dsize);
                /* Unlock the chain of this new record */
-               if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0)
+               if (tdb_unlock(tdb, tdb->travlocks.hash, tdb->travlocks.lock_rw) != 0)
                        TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n"));
        }
        /* Unlock the chain of old record */
-       if (tdb_unlock(tdb, BUCKET(oldhash), F_WRLCK) != 0)
+       if (tdb_unlock(tdb, BUCKET(oldhash), tdb->travlocks.lock_rw) != 0)
                TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_nextkey: WARNING tdb_unlock failed!\n"));
        return key;
 }