From 15e66ba37ae56787897e49039e217b5426924829 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 25 May 2001 00:48:28 +0000 Subject: Added tdb_change_int_atomic() to allow atomic updates of a tdb int value. Jeremy. (This used to be commit cf5015f15935605cf69078bc15251db61ddc48c7) --- source3/include/proto.h | 4 +++- source3/smbd/process.c | 12 ++++++------ source3/smbd/server.c | 8 +++----- source3/tdb/tdbutil.c | 35 ++++++++++++++++++++++++++++++++--- 4 files changed, 44 insertions(+), 15 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index d6bc3c768c..5c9a739caa 100644 --- a/source3/include/proto.h +++ b/source3/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/source3/smbd/process.c b/source3/smbd/process.c index 74c0cbc96f..1f575e2a46 100644 --- a/source3/smbd/process.c +++ b/source3/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/source3/smbd/server.c b/source3/smbd/server.c index 6f4f18562e..fcee30d667 100644 --- a/source3/smbd/server.c +++ b/source3/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/source3/tdb/tdbutil.c b/source3/tdb/tdbutil.c index a620f085a9..40f5a1246d 100644 --- a/source3/tdb/tdbutil.c +++ b/source3/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 */ -- cgit