dbwrap: Add dbwrap_do_locked
authorVolker Lendecke <vl@samba.org>
Wed, 9 Nov 2016 07:45:59 +0000 (08:45 +0100)
committerRalph Boehme <slow@samba.org>
Tue, 25 Jul 2017 15:43:16 +0000 (17:43 +0200)
With a proper implementation this enables modifications without
having to allocate a record. In really performance sensitive code
paths this matters.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
lib/dbwrap/dbwrap.c
lib/dbwrap/dbwrap.h
lib/dbwrap/dbwrap_private.h

index 260a977f9277dca2fd2c6bee28f991c0242872f7..22437f620834984a9d61aeaa434c7979a1762e38 100644 (file)
@@ -498,6 +498,42 @@ NTSTATUS dbwrap_parse_record_recv(struct tevent_req *req)
        return tevent_req_simple_recv_ntstatus(req);
 }
 
+NTSTATUS dbwrap_do_locked(struct db_context *db, TDB_DATA key,
+                         void (*fn)(struct db_record *rec,
+                                    void *private_data),
+                         void *private_data)
+{
+       struct db_record *rec;
+
+       if (db->do_locked != NULL) {
+               struct db_context **lockptr;
+               NTSTATUS status;
+
+               if (db->lock_order != DBWRAP_LOCK_ORDER_NONE) {
+                       dbwrap_lock_order_lock(db, &lockptr);
+               }
+
+               status = db->do_locked(db, key, fn, private_data);
+
+               if (db->lock_order != DBWRAP_LOCK_ORDER_NONE) {
+                       dbwrap_lock_order_unlock(db, lockptr);
+               }
+
+               return status;
+       }
+
+       rec = dbwrap_fetch_locked(db, db, key);
+       if (rec == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       fn(rec, private_data);
+
+       TALLOC_FREE(rec);
+
+       return NT_STATUS_OK;
+}
+
 int dbwrap_wipe(struct db_context *db)
 {
        if (db->wipe == NULL) {
index 04e179e75e6c226eaa3b0d3cd23357c420eac3e9..1161bf0a49333c020f1ed0880ec2b816dfbc0983 100644 (file)
@@ -83,6 +83,11 @@ struct db_record *dbwrap_try_fetch_locked(struct db_context *db,
                                          TDB_DATA key);
 struct db_context *dbwrap_record_get_db(struct db_record *rec);
 
+NTSTATUS dbwrap_do_locked(struct db_context *db, TDB_DATA key,
+                         void (*fn)(struct db_record *rec,
+                                    void *private_data),
+                         void *private_data);
+
 NTSTATUS dbwrap_delete(struct db_context *db, TDB_DATA key);
 NTSTATUS dbwrap_store(struct db_context *db, TDB_DATA key,
                      TDB_DATA data, int flags);
index 2858afd85397eb89a76fcc56284f14c45d18a085..e757215d3896a296c22cef1b317cc9ca66b7bec6 100644 (file)
@@ -68,6 +68,10 @@ struct db_context {
                void *private_data,
                enum dbwrap_req_state *req_state);
        NTSTATUS (*parse_record_recv)(struct tevent_req *req);
+       NTSTATUS (*do_locked)(struct db_context *db, TDB_DATA key,
+                             void (*fn)(struct db_record *rec,
+                                        void *private_data),
+                             void *private_data);
        int (*exists)(struct db_context *db,TDB_DATA key);
        int (*wipe)(struct db_context *db);
        int (*check)(struct db_context *db);