summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-05-25 00:48:28 +0000
committerJeremy Allison <jra@samba.org>2001-05-25 00:48:28 +0000
commitcf5015f15935605cf69078bc15251db61ddc48c7 (patch)
tree250e723f67b13002fc930e943d410f3a06e8f0a9
parent19145bae720bbcc32dcab380c62a33d1f0e3eef0 (diff)
downloadsamba-cf5015f15935605cf69078bc15251db61ddc48c7.tar.gz
samba-cf5015f15935605cf69078bc15251db61ddc48c7.tar.xz
samba-cf5015f15935605cf69078bc15251db61ddc48c7.zip
Added tdb_change_int_atomic() to allow atomic updates of a tdb int value.
Jeremy.
-rw-r--r--source/include/proto.h4
-rw-r--r--source/smbd/process.c12
-rw-r--r--source/smbd/server.c8
-rw-r--r--source/tdb/tdbutil.c35
4 files changed, 44 insertions, 15 deletions
diff --git a/source/include/proto.h b/source/include/proto.h
index d6bc3c768ce..5c9a739caa8 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -126,7 +126,8 @@ int sys_fsusage(const char *path, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
/* The following definitions come from lib/genrand.c */
-void generate_random_buffer( unsigned char *out, int len, BOOL re_seed);
+void set_rand_reseed_data(unsigned char *data, size_t len);
+void generate_random_buffer( unsigned char *out, int len, BOOL do_reseed_now);
char *generate_random_str(size_t len);
/* The following definitions come from lib/getsmbpass.c */
@@ -4589,6 +4590,7 @@ int tdb_store_int_byblob(TDB_CONTEXT *tdb, char *keystr, size_t len, int v);
int tdb_store_int(TDB_CONTEXT *tdb, char *keystr, int v);
int tdb_store_by_string(TDB_CONTEXT *tdb, char *keystr, void *buffer, int len);
TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, char *keystr);
+int tdb_change_int_atomic(TDB_CONTEXT *tdb, char *keystr, int *oldval, int change_val);
size_t tdb_pack(char *buf, int bufsize, char *fmt, ...);
int tdb_unpack(char *buf, int bufsize, char *fmt, ...);
diff --git a/source/smbd/process.c b/source/smbd/process.c
index 74c0cbc96f6..1f575e2a462 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -781,12 +781,12 @@ static BOOL smbd_process_limit(void)
/* Always add one to the smbd process count, as exit_server() always
* subtracts one.
*/
- tdb_lock_bystring(conn_tdb_ctx(), "INFO/total_smbds");
- total_smbds = tdb_fetch_int(conn_tdb_ctx(), "INFO/total_smbds");
- total_smbds = total_smbds < 0 ? 1 : total_smbds + 1;
- tdb_store_int(conn_tdb_ctx(), "INFO/total_smbds", total_smbds);
- tdb_unlock_bystring(conn_tdb_ctx(), "INFO/total_smbds");
-
+
+ total_smbds = 1; /* In case we need to create the entry. */
+
+ if (tdb_change_int_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, 1) == -1)
+ return True;
+
return total_smbds > lp_max_smbd_processes();
}
else
diff --git a/source/smbd/server.c b/source/smbd/server.c
index 6f4f18562ee..fcee30d6672 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -421,16 +421,14 @@ static BOOL dump_core(void)
/****************************************************************************
update the current smbd process count
****************************************************************************/
+
static void decrement_smbd_process_count(void)
{
int total_smbds;
if (lp_max_smbd_processes()) {
- tdb_lock_bystring(conn_tdb_ctx(), "INFO/total_smbds");
- if ((total_smbds = tdb_fetch_int(conn_tdb_ctx(), "INFO/total_smbds")) > 0)
- tdb_store_int(conn_tdb_ctx(), "INFO/total_smbds", total_smbds - 1);
-
- tdb_unlock_bystring(conn_tdb_ctx(), "INFO/total_smbds");
+ total_smbds = 0;
+ tdb_change_int_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, -1);
}
}
diff --git a/source/tdb/tdbutil.c b/source/tdb/tdbutil.c
index a620f085a90..40f5a1246d4 100644
--- a/source/tdb/tdbutil.c
+++ b/source/tdb/tdbutil.c
@@ -46,9 +46,6 @@ void tdb_unlock_bystring(TDB_CONTEXT *tdb, char *keyval)
tdb_chainunlock(tdb, key);
}
-/* lock a chain by string key */
-
-
/* fetch a value by a arbitrary blob key, return -1 if not found */
int tdb_fetch_int_byblob(TDB_CONTEXT *tdb, char *keyval, size_t len)
{
@@ -107,6 +104,7 @@ int tdb_store_by_string(TDB_CONTEXT *tdb, char *keystr, void *buffer, int len)
/* Fetch a buffer using a null terminated string key. Don't forget to call
free() on the result dptr. */
+
TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, char *keystr)
{
TDB_DATA key;
@@ -117,6 +115,37 @@ TDB_DATA tdb_fetch_by_string(TDB_CONTEXT *tdb, char *keystr)
return tdb_fetch(tdb, key);
}
+/* Atomic integer change. Returns old value. To create, set initial value in *oldval. */
+
+int tdb_change_int_atomic(TDB_CONTEXT *tdb, char *keystr, int *oldval, int change_val)
+{
+ int val;
+ int ret = -1;
+
+ if (tdb_lock_bystring(tdb, keystr) == -1)
+ return -1;
+
+ if ((val = tdb_fetch_int(tdb, keystr)) == -1) {
+ if (tdb_error(tdb) != TDB_ERR_NOEXIST)
+ goto err_out;
+
+ val = *oldval;
+
+ } else {
+ *oldval = val;
+ val += change_val;
+ }
+
+ if (tdb_store_int(tdb, keystr, val) == -1)
+ goto err_out;
+
+ ret = 0;
+
+ err_out:
+
+ tdb_unlock_bystring(tdb, keystr);
+ return ret;
+}
/* useful pair of routines for packing/unpacking data consisting of
integers and strings */