[SCM] Samba Shared Repository - branch v4-23-stable updated

Björn Jacke bjacke at samba.org
Tue Sep 1 21:56:39 UTC 2026


The branch, v4-23-stable has been updated
       via  20410eaf85f VERSION: Disable GIT_SNAPSHOT for the 4.23.12 release.
       via  34922d8c917 WHATSNEW: Add release notes for Samba 4.23.12.
       via  a4ed25f7aa9 s4:rpc_server/dnsserver: allow dnsserver_db_do_reset_dword() to add new dNSProperty values
       via  eecb39591d0 s4:rpc_server/dnsserver: fix talloc hierarchy in dnsserver_db_do_reset_dword()
       via  7b9d77d6f92 python/tests: add tests for samba-tool dns zoneoptions on a zone without dNSProperty values
       via  ba69c33d8a9 s4:dns_server: change DNS_MAX_UDP_PACKET_LENGTH to 512
       via  8e463b77be1 python:tests/dns: use tcp for the CVE-2018-14629 regression tests
       via  ef9728257c0 s4:dns_server: avoid layer violation for truncated udp responses.
       via  4d49bc4070f s4:dns_server: make it more obvious that the DNS over TCP length hdr is u16
       via  ba06fd2f0db s4/dns_server: truncate large dns packets over udp and set truncated flag
       via  083cc719441 s4/dns_server: add large dns udp truncated packets tests
       via  77d1c22f454 s4:kcc: let dns_tombstone_records_zone() skip if fAging is not 1
       via  fb24eebc21c s4:dns_server: let dns_get_zone_properties() fallback to serverinfo->dwDefault[No]RefreshInterval
       via  c3fa91ca9ea s4:dns_server: move rpc_server/dnsserver/dnsutils.c to dns_server/dnsserver_utils.c
       via  ded1137de43 s4:dns_server: let dns_get_zone_properties() initialize zoneinfo completely.
       via  67b581726d9 s4:rpc_server/dnsserver: let dnsserver_init_zoneinfo() fallback to serverinfo->dwDefault[No]RefreshInterval
       via  5b894bb9f87 s4:rpc_server/dnsserver: define DNS_SERVER_DEFAULT_[NO_]REFRESH_INTERVAL as 24 * 7
       via  9f15e0b2e51 s4:rpc_server/dnsserver: let dnsserver_init_serverinfo() use dns_server_scavenging_interval()
       via  6c438d64347 s4:kcc: let kccsrv_dns_zone_scavenging() use dns_server_scavenging_interval()
       via  86651510ebd s4:dns_server: add dns_server_scavenging_interval()
       via  346f4c3d7af s4:rpc_server/common: turn lpcfg_dcerpc_server_info() into an inline function
       via  49055d1bf7b script/autobuild.py: also add .stderr output including backtraces
       via  4bcd54d2e39 ctdb-recoverd: Ensure an outgoing leader aborts recovery
       via  0f958a42524 ctdb-recoverd: Factor out fetching node map and local flags
       via  920ba1531fb s3:vfs_streams_xattr: Use dirfsp in streams_xattr_unlinkat()
       via  d1232044920 s3:smbd: Allow STREAM_INFORMATION query on alternate stream handles
       via  4b820c0b0a9 s4:torture: Close all handles in test_stream_io() in smb2.streams
       via  3ba08bce53a s4:torture: Use torture_result() in check_stream_list() in smb2.streams
       via  0fec7d8b4ac s4:torture: Move smb2_util_close() do done in create_file_with_stream()
       via  795e7173c23 s4:torture: Add missing CHECK_STATUS() in test_stream_io()
       via  d4489e5ab2c s4:torture: Cleanup to to use the right name
       via  709b2b032d6 s4:torture: Make sure we close handles correctly in test_stream_names()
       via  83670545543 s4:torture: Always close handle in check_stream() in smb2.streams
       via  e91dd88bb3c s4:torture: Close handles opened by torture_smb2_testdir() in smb2.streams test
       via  96c7be3b2e2 libcli/dns: Do not pass NULL pointer to memcpy()
       via  57e14d461fb libcli/dns: Add dns_cli_request() sync wrapper
       via  a39ca9d21bc libcli/dns: Make dns_cli_request_send() take a dns_name_packet()
       via  599f5fcf2da libcli/dns: fix use-after-free oom case
       via  f8365769831 libcli/dns: Add TCP parallel fallback after 1 second UDP timeout
       via  c0830db3dfc libcli/dns: Make SMB_ASSERT available
       via  d1c14f5ca88 libcli/dns: dns_udp_request_get_reply -> dns_udp_request_sent
       via  f7fd813a942 libcli/dns: Avoid a local variable referenced only once
       via  4cc3cfc3d5f libcli/dns: Simplify dns over tcp requests, save 39 lines :-)
       via  6f18d569c7b librpc/ndr: fix ndr_{push,pull,print}_{timeval,timespec}() and add _legacy() compat
       via  23a748cf39e third_party: Update cmocka to version 1.1.6
       via  b73a7d4188d s4:dsdb: Do not declare cm_print_error()
       via  1ea76986e4b libcli:ldap: Do not declare cm_print_error()
       via  c6c02cffa96 s4:kdc: Fix cmocka.h include
       via  43643e440db Add missing include needed for cmocka.h
       via  7453861edd5 lib/pthreadpool: protect jobs list from concurrent thread access
       via  4a91dbc154a lib/pthreadpool: Fix possible concurrent access to pool->glue_list
       via  eea5953d2d7 lib/pthreadpool: fix free of already freed glue object
       via  cc8dddc1010 Add unit cmocka tests for pthreadpool_tevent
       via  424dfe405dc selftest: mark "smb2.lease.two-leases" as flapping
       via  d57ed1c0927 python/tests: catch NT_STATUS_IO_TIMEOUT from witness.witness() as AssertionError()
       via  948b4f39ae7 selftest: mark RpcdWitnessSambaTests as flapping
       via  1e3082b026a VERSION: Bump version up to Samba 4.23.12...
      from  41a080b98e5 VERSION: Disable GIT_SNAPSHOT for the 4.23.11 release.

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-23-stable


- Log -----------------------------------------------------------------
-----------------------------------------------------------------------

Summary of changes:
 VERSION                                            |   2 +-
 WHATSNEW.txt                                       |  91 ++-
 buildtools/wafsamba/samba_third_party.py           |   2 +-
 ctdb/server/ctdb_recoverd.c                        |  58 +-
 lib/audit_logging/tests/audit_logging_error_test.c |   1 +
 lib/audit_logging/tests/audit_logging_test.c       |   1 +
 lib/compression/tests/test_lzx_huffman.c           |   1 +
 lib/compression/tests/test_lzxpress_plain.c        |   1 +
 lib/ldb/tests/test_ldb_comparison_fold.c           |   1 +
 lib/param/param.h                                  |   1 -
 lib/pthreadpool/pthreadpool_tevent.c               | 121 +++-
 lib/pthreadpool/test_pthreadpool_tevent.c          | 777 +++++++++++++++++++++
 lib/pthreadpool/tests_cmocka.c                     |   1 +
 lib/pthreadpool/wscript_build                      |   6 +
 lib/util/tests/test_stable_sort.c                  |   1 +
 libcli/dns/dns.c                                   | 530 ++++++++------
 libcli/dns/dns_lookup.c                            |  16 +-
 libcli/dns/libdns.h                                |  13 +-
 libcli/dns/wscript_build                           |   2 +-
 libcli/drsuapi/tests/test_repl_decrypt.c           |   1 +
 libcli/ldap/tests/ldap_message_test.c              |   6 +-
 libcli/security/tests/test_run_conditional_ace.c   |   1 +
 libcli/security/tests/test_sddl_conditional_ace.c  |   1 +
 librpc/ABI/{ndr-6.0.0.sigs => ndr-6.1.0.sigs}      |  14 +-
 librpc/idl/misc.idl                                |  13 +
 librpc/ndr/libndr.h                                |  18 +
 librpc/ndr/ndr_basic.c                             |  92 +++
 librpc/wscript_build                               |   2 +-
 .../tests/blackbox/rpcd_witness_samba_only.py      |  28 +-
 python/samba/tests/dns.py                          | 127 +++-
 python/samba/tests/samba_tool/dnscmd.py            |  72 +-
 script/autobuild.py                                |  39 +-
 selftest/flapping.d/smb2.lease                     |   1 +
 selftest/flapping.d/witness                        |   1 +
 selftest/knownfail.d/dns                           |   2 +
 source3/librpc/idl/open_files.idl                  |  10 +-
 source3/modules/vfs_streams_xattr.c                |   2 +-
 source3/selftest/tests.py                          |   2 +
 source3/smbd/smb2_trans2.c                         |   5 +-
 source4/auth/tests/heimdal_unwrap_des.c            |   1 +
 source4/dns_server/dns_query.c                     |  13 +-
 source4/dns_server/dns_server.c                    |  79 ++-
 source4/dns_server/dns_server.h                    |  11 +
 source4/dns_server/dnsserver_common.c              |  73 +-
 source4/dns_server/dnsserver_common.h              |   5 +
 .../dnsutils.c => dns_server/dnsserver_utils.c}    |  35 +-
 source4/dns_server/wscript_build                   |   4 +-
 source4/dsdb/kcc/kcc_periodic.c                    |  12 +-
 source4/dsdb/kcc/scavenge_dns_records.c            |  16 +
 .../dsdb/samdb/ldb_modules/tests/test_audit_log.c  |   1 +
 .../ldb_modules/tests/test_audit_log_errors.c      |   1 +
 .../dsdb/samdb/ldb_modules/tests/test_audit_util.c |   1 +
 .../ldb_modules/tests/test_encrypted_secrets.c     |   1 +
 .../samdb/ldb_modules/tests/test_group_audit.c     |   6 +-
 .../ldb_modules/tests/test_group_audit_errors.c    |   1 +
 .../ldb_modules/tests/test_unique_object_sids.c    |   1 +
 source4/kdc/tests/db-glue-test.c                   |   3 +-
 source4/rpc_server/common/common.h                 |  26 +
 source4/rpc_server/common/loadparm.c               |  45 --
 source4/rpc_server/dnsserver/dnsdb.c               | 157 +++--
 source4/rpc_server/dnsserver/dnsserver.h           |  16 +
 .../tests/rpc_dns_server_dnsutils_test.c           |   3 +-
 source4/rpc_server/wscript_build                   |   2 -
 source4/torture/smb2/streams.c                     |  89 ++-
 testsuite/unittests/test_krb5_samba.c              |   1 +
 testsuite/unittests/test_lib_util_modules.c        |   1 +
 third_party/cmocka/cmocka.c                        | 357 +++++++---
 third_party/cmocka/cmocka.h                        | 203 +++++-
 third_party/cmocka/cmocka_private.h                |   2 +
 69 files changed, 2695 insertions(+), 534 deletions(-)
 create mode 100644 lib/pthreadpool/test_pthreadpool_tevent.c
 copy librpc/ABI/{ndr-6.0.0.sigs => ndr-6.1.0.sigs} (97%)
 create mode 100644 selftest/flapping.d/witness
 rename source4/{rpc_server/dnsserver/dnsutils.c => dns_server/dnsserver_utils.c} (93%)
 delete mode 100644 source4/rpc_server/common/loadparm.c


Changeset truncated at 500 lines:

diff --git a/VERSION b/VERSION
index 02c8eed067f..18695bef04b 100644
--- a/VERSION
+++ b/VERSION
@@ -27,7 +27,7 @@ SAMBA_COPYRIGHT_STRING="Copyright Andrew Tridgell and the Samba Team 1992-2025"
 ########################################################
 SAMBA_VERSION_MAJOR=4
 SAMBA_VERSION_MINOR=23
-SAMBA_VERSION_RELEASE=11
+SAMBA_VERSION_RELEASE=12
 
 ########################################################
 # If a official release has a serious bug              #
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index ab60a61150e..0ee57b93433 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,3 +1,91 @@
+                   ===============================
+                   Release Notes for Samba 4.23.12
+                         September 01, 2026
+                   ===============================
+
+
+This is the latest stable release of the Samba 4.23 release series.
+
+
+Changes since 4.23.11
+---------------------
+
+o  Ralph Boehme <slow at samba.org>
+   * BUG 15978: leases torture test flappy (marked flappy)
+
+o  Volker Lendecke <vl at samba.org>
+   * BUG 16225: dns client problems related to EDNS usage
+
+o  Andréas Leroux <aleroux at tranquil.it>
+   * BUG 15988: Samba internal DNS service doesn't handle switch from UDP to TCP
+     when packet is larger than 4k
+
+o  Stefan Metzmacher <metze at samba.org>
+   * BUG 15988: Samba internal DNS service doesn't handle switch from UDP to TCP
+     when packet is larger than 4k
+   * BUG 16077: witness test flappy needs to be fixed
+   * BUG 16194: autobuild failures need to be reported in a more verbose way
+   * BUG 16199: ndr_{push,pull,print}_{timeval,timespec} encode/decode the value
+     twice
+   * BUG 16223: DNS scavenging happens even if fAging is FALSE
+   * BUG 16226: samba-tool dns zoneoptions $DC_SERVER_IP
+     _msdcs.addom.samba.example.com -P --aging=1 gives
+     WERR_INTERNAL_DB_ERROR
+
+o  Noel Power <noel.power at suse.com>
+   * BUG 15957: Double free of glue object  and core in
+     pthreadpool_tevent_register_ev
+   * BUG 15958: pthreadpool_tevent has race conditions accessing both
+     pthreadpool_tevent.jobs list and pthreadpool_tevent.glue_list
+
+o  Noel Power <nopower at suse.com>
+   * BUG 15958: pthreadpool_tevent has race conditions accessing both
+     pthreadpool_tevent.jobs list and pthreadpool_tevent.glue_list
+
+o  Anoop C S <anoopcs at samba.org>
+   * BUG 16188: Build failure with cmocka >= 2.0: cm_print_error() conflicts
+     with cmocka.h macro
+
+o  Andreas Schneider <asn at samba.org>
+   * BUG 16144: Incorrect behavior on stream create-disposition when prior
+     handle is closed
+   * BUG 16188: Build failure with cmocka >= 2.0: cm_print_error() conflicts
+     with cmocka.h macro
+
+o  Martin Schwenke <mschwenke at ddn.com>
+   * BUG 16082: An inactive node can run recovery resulting in inconsistent
+     databases
+
+o  Shachar Sharon <ssharon at redhat.com>
+   * BUG 16225: dns client problems related to EDNS usage
+
+o  Jennifer Sutton <jennifersutton at catalyst.net.nz>
+   * BUG 16225: dns client problems related to EDNS usage
+
+
+#######################################
+Reporting bugs & Development Discussion
+#######################################
+
+Please discuss this release on the samba-technical mailing list or by
+joining the #samba-technical:matrix.org matrix room, or
+#samba-technical IRC channel on irc.libera.chat.
+
+If you do report problems then please try to send high quality
+feedback. If you don't provide vital information to help us track down
+the problem then you will probably be ignored.  All bug reports should
+be filed under the Samba 4.1 and newer product in the project's Bugzilla
+database (https://bugzilla.samba.org/).
+
+
+======================================================================
+== Our Code, Our Bugs, Our Responsibility.
+== The Samba Team
+======================================================================
+
+
+Release notes for older releases follow:
+----------------------------------------
                    ===============================
                    Release Notes for Samba 4.23.11
                            August 03, 2026
@@ -74,8 +162,7 @@ database (https://bugzilla.samba.org/).
 ======================================================================
 
 
-Release notes for older releases follow:
-----------------------------------------
+----------------------------------------------------------------------
                    ===============================
                    Release Notes for Samba 4.23.10
                            July 28, 2026
diff --git a/buildtools/wafsamba/samba_third_party.py b/buildtools/wafsamba/samba_third_party.py
index 8f0c56dec79..2761ffa2036 100644
--- a/buildtools/wafsamba/samba_third_party.py
+++ b/buildtools/wafsamba/samba_third_party.py
@@ -18,7 +18,7 @@ Build.BuildContext.CHECK_POPT = CHECK_POPT
 
 @conf
 def CHECK_CMOCKA(conf):
-    return conf.CHECK_BUNDLED_SYSTEM_PKG('cmocka', minversion='1.1.3')
+    return conf.CHECK_BUNDLED_SYSTEM_PKG('cmocka', minversion='1.1.6')
 
 Build.BuildContext.CHECK_CMOCKA = CHECK_CMOCKA
 
diff --git a/ctdb/server/ctdb_recoverd.c b/ctdb/server/ctdb_recoverd.c
index 2e56fb77f31..9c206b3a3cf 100644
--- a/ctdb/server/ctdb_recoverd.c
+++ b/ctdb/server/ctdb_recoverd.c
@@ -1279,6 +1279,37 @@ done:
 	return ok;
 }
 
+static struct ctdb_node_map_old *update_node_map_and_flags(
+	struct ctdb_recoverd *rec)
+{
+	struct ctdb_context *ctdb = rec->ctdb;
+	struct ctdb_node_map_old *nodemap = NULL;
+	unsigned int i = 0;
+	int ret = 0;
+
+	ret = ctdb_ctrl_getnodemap(ctdb,
+				   CONTROL_TIMEOUT(),
+				   rec->pnn,
+				   rec,
+				   &nodemap);
+	if (ret != 0) {
+		return NULL;
+	}
+
+	talloc_free(rec->nodemap);
+	rec->nodemap = nodemap;
+
+	/* Remember this node's flags */
+	for (i = 0; i < nodemap->num; i++) {
+		if (nodemap->nodes[i].pnn == rec->pnn) {
+			rec->node_flags = nodemap->nodes[i].flags;
+			break;
+		}
+	}
+
+	return nodemap;
+}
+
 static int db_recovery_parallel(struct ctdb_recoverd *rec, TALLOC_CTX *mem_ctx)
 {
 	static char prog[PATH_MAX+1] = "";
@@ -1307,13 +1338,24 @@ static int db_recovery_parallel(struct ctdb_recoverd *rec, TALLOC_CTX *mem_ctx)
 static int do_recovery(struct ctdb_recoverd *rec, TALLOC_CTX *mem_ctx)
 {
 	struct ctdb_context *ctdb = rec->ctdb;
-	struct ctdb_node_map_old *nodemap = rec->nodemap;
+	struct ctdb_node_map_old *nodemap = NULL;
 	unsigned int i;
 	int ret;
 	bool self_ban;
 
 	DBG_NOTICE("Starting do_recovery\n");
 
+	nodemap = update_node_map_and_flags(rec);
+	if (nodemap == NULL) {
+		DBG_ERR("Unable to get nodemap from node %"PRIu32"\n", rec->pnn);
+		return -1;
+	}
+
+	if (!this_node_can_be_leader(rec)) {
+		DBG_ERR("This node can no longer be leader, abort recovery\n");
+		return -1;
+	}
+
 	/* Check if the current node is still the leader.  It's possible that
 	 * re-election has changed the leader.
 	 */
@@ -2601,21 +2643,11 @@ static void main_loop(struct ctdb_context *ctdb, struct ctdb_recoverd *rec,
 		return;
 	}
 
-	/* get nodemap */
-	ret = ctdb_ctrl_getnodemap(ctdb,
-				   CONTROL_TIMEOUT(),
-				   rec->pnn,
-				   rec,
-				   &nodemap);
-	if (ret != 0) {
+	nodemap = update_node_map_and_flags(rec);
+	if (nodemap == NULL) {
 		DBG_ERR("Unable to get nodemap from node %"PRIu32"\n", rec->pnn);
 		return;
 	}
-	talloc_free(rec->nodemap);
-	rec->nodemap = nodemap;
-
-	/* remember our own node flags */
-	rec->node_flags = nodemap->nodes[rec->pnn].flags;
 
 	ban_misbehaving_nodes(rec, &self_ban);
 	if (self_ban) {
diff --git a/lib/audit_logging/tests/audit_logging_error_test.c b/lib/audit_logging/tests/audit_logging_error_test.c
index 12a81ff018d..595293b7dd1 100644
--- a/lib/audit_logging/tests/audit_logging_error_test.c
+++ b/lib/audit_logging/tests/audit_logging_error_test.c
@@ -43,6 +43,7 @@
 #include <stdarg.h>
 #include <stddef.h>
 #include <setjmp.h>
+#include <stdint.h>
 #include <cmocka.h>
 
 #include "includes.h"
diff --git a/lib/audit_logging/tests/audit_logging_test.c b/lib/audit_logging/tests/audit_logging_test.c
index 09238823399..ed189dabb8f 100644
--- a/lib/audit_logging/tests/audit_logging_test.c
+++ b/lib/audit_logging/tests/audit_logging_test.c
@@ -41,6 +41,7 @@
 #include <stdarg.h>
 #include <stddef.h>
 #include <setjmp.h>
+#include <stdint.h>
 #include <cmocka.h>
 
 #include <string.h>
diff --git a/lib/compression/tests/test_lzx_huffman.c b/lib/compression/tests/test_lzx_huffman.c
index 7770535c1e9..aaffb5503e0 100644
--- a/lib/compression/tests/test_lzx_huffman.c
+++ b/lib/compression/tests/test_lzx_huffman.c
@@ -24,6 +24,7 @@
 
 #include <stdarg.h>
 #include <stddef.h>
+#include <stdint.h>
 #include <setjmp.h>
 #include <cmocka.h>
 #include <stdbool.h>
diff --git a/lib/compression/tests/test_lzxpress_plain.c b/lib/compression/tests/test_lzxpress_plain.c
index 1c147932d40..86d7d80c0ed 100644
--- a/lib/compression/tests/test_lzxpress_plain.c
+++ b/lib/compression/tests/test_lzxpress_plain.c
@@ -20,6 +20,7 @@
 
 #include <stdarg.h>
 #include <stddef.h>
+#include <stdint.h>
 #include <setjmp.h>
 #include <sys/stat.h>
 #include <cmocka.h>
diff --git a/lib/ldb/tests/test_ldb_comparison_fold.c b/lib/ldb/tests/test_ldb_comparison_fold.c
index 601cfe6c482..6c5a75ed74d 100644
--- a/lib/ldb/tests/test_ldb_comparison_fold.c
+++ b/lib/ldb/tests/test_ldb_comparison_fold.c
@@ -21,6 +21,7 @@
 #include <stdarg.h>
 #include <stddef.h>
 #include <setjmp.h>
+#include <stdint.h>
 #include <cmocka.h>
 #include <stdbool.h>
 #include "replace.h"
diff --git a/lib/param/param.h b/lib/param/param.h
index ef678a1cbd6..603a8358faa 100644
--- a/lib/param/param.h
+++ b/lib/param/param.h
@@ -188,7 +188,6 @@ void lpcfg_smbcli_options(struct loadparm_context *lp_ctx,
 void lpcfg_smbcli_session_options(struct loadparm_context *lp_ctx,
 				 struct smbcli_session_options *options);
 const char *lpcfg_socket_options(struct loadparm_context *);
-struct dcerpc_server_info *lpcfg_dcerpc_server_info(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx);
 struct gensec_settings *lpcfg_gensec_settings(TALLOC_CTX *, struct loadparm_context *);
 
 /* The following definitions come from param/util.c  */
diff --git a/lib/pthreadpool/pthreadpool_tevent.c b/lib/pthreadpool/pthreadpool_tevent.c
index a66f444d193..422a88c784a 100644
--- a/lib/pthreadpool/pthreadpool_tevent.c
+++ b/lib/pthreadpool/pthreadpool_tevent.c
@@ -19,6 +19,7 @@
 
 #include "replace.h"
 #include "system/filesys.h"
+#include "system/threads.h"
 #include "pthreadpool_tevent.h"
 #include "pthreadpool.h"
 #include "lib/util/tevent_unix.h"
@@ -57,8 +58,17 @@ struct pthreadpool_tevent_glue_ev_link {
 struct pthreadpool_tevent {
 	struct pthreadpool *pool;
 	struct pthreadpool_tevent_glue *glue_list;
+	/*
+	 * Control access to the glue_list
+	 */
+	pthread_mutex_t glue_mutex;
 
 	struct pthreadpool_tevent_job_state *jobs;
+	/*
+	 * Control access to the jobs
+	 */
+	pthread_mutex_t jobs_mutex;
+
 };
 
 struct pthreadpool_tevent_job_state {
@@ -97,6 +107,19 @@ int pthreadpool_tevent_init(TALLOC_CTX *mem_ctx, unsigned max_threads,
 		return ret;
 	}
 
+	ret = pthread_mutex_init(&pool->glue_mutex, NULL);
+	if (ret != 0) {
+		TALLOC_FREE(pool);
+		return ret;
+	}
+
+	ret = pthread_mutex_init(&pool->jobs_mutex, NULL);
+	if (ret != 0) {
+		pthread_mutex_destroy(&pool->glue_mutex);
+		TALLOC_FREE(pool);
+		return ret;
+	}
+
 	talloc_set_destructor(pool, pthreadpool_tevent_destructor);
 
 	*presult = pool;
@@ -132,12 +155,26 @@ static int pthreadpool_tevent_destructor(struct pthreadpool_tevent *pool)
 		return ret;
 	}
 
+	ret = pthread_mutex_lock(&pool->jobs_mutex);
+	if (ret != 0 ) {
+		return ret;
+	}
 	for (state = pool->jobs; state != NULL; state = next) {
 		next = state->next;
 		DLIST_REMOVE(pool->jobs, state);
 		state->pool = NULL;
 	}
 
+	ret = pthread_mutex_unlock(&pool->jobs_mutex);
+	if (ret != 0 ) {
+		return ret;
+	}
+
+	ret = pthread_mutex_lock(&pool->glue_mutex);
+	if (ret != 0) {
+		return ret;
+	}
+
 	/*
 	 * Delete all the registered
 	 * tevent_context/tevent_threaded_context
@@ -147,6 +184,11 @@ static int pthreadpool_tevent_destructor(struct pthreadpool_tevent *pool)
 		/* The glue destructor removes it from the list */
 		TALLOC_FREE(glue);
 	}
+
+	pthread_mutex_unlock(&pool->glue_mutex);
+	pthread_mutex_destroy(&pool->jobs_mutex);
+	pthread_mutex_destroy(&pool->glue_mutex);
+
 	pool->glue_list = NULL;
 
 	ret = pthreadpool_destroy(pool->pool);
@@ -158,6 +200,16 @@ static int pthreadpool_tevent_destructor(struct pthreadpool_tevent *pool)
 	return 0;
 }
 
+/*
+ * glue destruction is only called with
+ * glue_mutex already locked either from
+ *   a) pthreadpool_tevent_destructor or
+ *   b) pthreadpool_tevent_glue_link_destructor
+ * pthreadpool_tevent_destructor accesses
+ * the glue_list while calling pthreadpool_tevent_glue_destructor
+ * which modifies the glue_list so it needs the lock held while
+ * doing that.
+ */
 static int pthreadpool_tevent_glue_destructor(
 	struct pthreadpool_tevent_glue *glue)
 {
@@ -190,7 +242,21 @@ static int pthreadpool_tevent_glue_destructor(
 static int pthreadpool_tevent_glue_link_destructor(
 	struct pthreadpool_tevent_glue_ev_link *ev_link)
 {
-	TALLOC_FREE(ev_link->glue);
+	if (ev_link->glue) {
+		int ret;
+		/* save the mutex */
+		pthread_mutex_t *glue_mutex =
+			&ev_link->glue->pool->glue_mutex;
+		ret = pthread_mutex_lock(glue_mutex);
+		if (ret != 0) {
+			return ret;
+		}
+		TALLOC_FREE(ev_link->glue);
+		ret = pthread_mutex_unlock(glue_mutex);
+		if (ret != 0) {
+			return ret;
+		}
+	}
 	return 0;
 }
 
@@ -199,7 +265,12 @@ static int pthreadpool_tevent_register_ev(struct pthreadpool_tevent *pool,
 {
 	struct pthreadpool_tevent_glue *glue = NULL;
 	struct pthreadpool_tevent_glue_ev_link *ev_link = NULL;
+	int ret;
 
+	ret = pthread_mutex_lock(&pool->glue_mutex);
+	if (ret != 0) {
+		return ret;
+	}
 	/*
 	 * See if this tevent_context was already registered by
 	 * searching the glue object list. If so we have nothing
@@ -208,10 +279,18 @@ static int pthreadpool_tevent_register_ev(struct pthreadpool_tevent *pool,
 	 */
 	for (glue = pool->glue_list; glue != NULL; glue = glue->next) {
 		if (glue->ev == ev) {
+			ret = pthread_mutex_unlock(&pool->glue_mutex);
+			if (ret != 0) {
+				return ret;
+			}
 			return 0;
 		}
 	}
 
+	ret = pthread_mutex_unlock(&pool->glue_mutex);
+	if (ret != 0) {
+		return ret;
+	}
 	/*
 	 * Event context not yet registered - create a new glue
 	 * object containing a tevent_context/tevent_threaded_context
@@ -250,12 +329,21 @@ static int pthreadpool_tevent_register_ev(struct pthreadpool_tevent *pool,
 	glue->tctx = tevent_threaded_context_create(glue, ev);
 	if (glue->tctx == NULL) {
 		TALLOC_FREE(ev_link);
-		TALLOC_FREE(glue);
 		return ENOMEM;
 	}
 #endif
 
+	ret = pthread_mutex_lock(&pool->glue_mutex);
+	if (ret != 0) {
+		return ret;
+	}
+
 	DLIST_ADD(pool->glue_list, glue);
+
+	ret = pthread_mutex_unlock(&pool->glue_mutex);
+	if (ret != 0) {
+		return ret;
+	}
 	return 0;
 }
 
@@ -339,8 +427,17 @@ struct tevent_req *pthreadpool_tevent_job_send(
 	 */
 	talloc_set_destructor(state, pthreadpool_tevent_job_state_destructor);
 
+	ret = pthread_mutex_lock(&pool->jobs_mutex);
+	if (tevent_req_error(req, ret)) {
+		return tevent_req_post(req, ev);
+	}
 	DLIST_ADD_END(pool->jobs, state);
 
+	ret = pthread_mutex_unlock(&pool->jobs_mutex);
+	if (tevent_req_error(req, ret)) {
+		return tevent_req_post(req, ev);
+	}
+
 	return req;
 }
 
@@ -360,6 +457,7 @@ static int pthreadpool_tevent_job_signal(int jobid,
 		job_private_data, struct pthreadpool_tevent_job_state);


-- 
Samba Shared Repository



More information about the samba-cvs mailing list