[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-1530-g404327a

Derrell Lipman derrell at samba.org
Mon May 11 02:46:03 GMT 2009


The branch, master has been updated
       via  404327ad41c5f24f9ace5cad31509149d87197fd (commit)
       via  db69ebcbcebbd3882d2eee7df8de15c3dc9c309b (commit)
       via  418a2eeae8912d14e32b0119232b897e78221037 (commit)
       via  d3434477e6d42432a0acf426fcfbe39eb11b1fd0 (commit)
      from  831b73ec82717c3c73ea1250f9c94228d251c1ec (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 404327ad41c5f24f9ace5cad31509149d87197fd
Author: Derrell Lipman <derrell at dworkin.(none)>
Date:   Sun May 10 22:40:20 2009 -0400

    Panic upon mutex lock or unlock failure
    
    - It's a serious error if we can't lock or unlock a mutex in
      smb_thread_once(). Panic instead of just displaying a DEBUG message.
    
    Derrell

commit db69ebcbcebbd3882d2eee7df8de15c3dc9c309b
Author: Derrell Lipman <derrell at dworkin.(none)>
Date:   Sun May 10 22:31:37 2009 -0400

    Provide a libsmbclient interface for programs requiring threads
    
    - This adds two functions: smbc_thread_posix() which provides access to the
      internal threading implementation using pthread; and smbc_thread_impl()
      where the user provides each of the functions required by Samba, to give
      access to the thread implementation's native capabilities.
    
    Derrell

commit 418a2eeae8912d14e32b0119232b897e78221037
Author: Derrell Lipman <derrell at dworkin.(none)>
Date:   Sun May 10 22:27:54 2009 -0400

    Don't require external use of internal enum smb_thread_lock_type
    
    - Internally, when locking or unlocking a mutex, we'll pass one of the
      values of enum smb_thread_lock_type. That enum is not available to users
      providing a thread implementation. Externally, we'll document the integer
      values which will be passed to their lock_mutex function, but not require
      them to access our internal header file.
    
    Derrell

commit d3434477e6d42432a0acf426fcfbe39eb11b1fd0
Author: Derrell Lipman <derrell at dworkin.(none)>
Date:   Sun May 10 21:55:23 2009 -0400

    Replace external thread "once" with an internal implementation
    
    Jeremy, please check...
    
    - I'm in the process of providing an interface in libsmbclient to the
      recently-added threading capabilities. In the process, I discovered that
      different thread implementations have varying types for the variable passed
      to the thread_impl_once() function. pthreads, for example, uses type
      pthread_once_t. Since Samba needs to internally declare these variables, it
      would need to know the exact type required by each thread implementation's
      function. After considering multiple methods of obtaining an appropriately
      sized variable, I decided that for the basic "once" functionality required
      by Samba, it would be much simpler to just implement our own "once"
      functionality. We don't require cancellation points et all. This commit adds
      an smb_thread_once() function that is implemented using an internal
      mutex. The mutex itself uses the implementation's create_mutex
      function. This eliminates the need for the user to provide a smb_thread_once
      function pointer and the entire issue of that function's first parameter.
    
    Derrell

-----------------------------------------------------------------------

Summary of changes:
 lib/util/smb_threads.c               |   64 +++++++++++++++++-
 lib/util/smb_threads.h               |   29 ++------
 lib/util/smb_threads_internal.h      |    2 +-
 source3/Makefile.in                  |    4 +-
 source3/include/libsmbclient.h       |  109 +++++++++++++++++++++++++++++
 source3/libsmb/libsmb_thread_impl.c  |  127 ++++++++++++++++++++++++++++++++++
 source3/libsmb/libsmb_thread_posix.c |   49 +++++++++++++
 7 files changed, 358 insertions(+), 26 deletions(-)
 create mode 100644 source3/libsmb/libsmb_thread_impl.c
 create mode 100644 source3/libsmb/libsmb_thread_posix.c


Changeset truncated at 500 lines:

diff --git a/lib/util/smb_threads.c b/lib/util/smb_threads.c
index 1998211..132ad48 100644
--- a/lib/util/smb_threads.c
+++ b/lib/util/smb_threads.c
@@ -40,6 +40,13 @@ const struct smb_thread_functions *global_tfp;
 void **global_lock_array;
 
 /*********************************************************
+ Mutex used for our internal "once" function
+*********************************************************/
+
+void *once_mutex = NULL;
+
+
+/*********************************************************
  Function to set the locking primitives used by libsmbclient.
 *********************************************************/
 
@@ -80,9 +87,64 @@ int smb_thread_set_functions(const struct smb_thread_functions *tf)
 		SAFE_FREE(name);
 	}
 
+        /* Create the mutex we'll use for our "once" function */
+	if (SMB_THREAD_CREATE_MUTEX("smb_once", once_mutex) != 0) {
+		smb_panic("smb_thread_set_functions: failed to create 'once' mutex");
+	}
+
 	return 0;
 }
 
+/*******************************************************************
+ Call a function only once. We implement this ourselves
+ using our own mutex rather than using the thread implementation's
+ *_once() function because each implementation has its own
+ type for the variable which keeps track of whether the function
+ has been called, and there's no easy way to allocate the correct
+ size variable in code internal to Samba without knowing the
+ implementation's "once" type.
+********************************************************************/
+void smb_thread_once(smb_thread_once_t *ponce, void (*init_fn)(void))
+{
+        int ret;
+        int need_func_call;
+
+        /* Lock our "once" mutex in order to test and initialize ponce */
+	if ((ret = SMB_THREAD_LOCK(once_mutex, SMB_THREAD_LOCK)) != 0) {
+                smb_panic("error locking 'once'");
+	}
+
+        /* Store whether we're going to need to issue the function call */
+        need_func_call = ! *ponce;
+
+        /*
+         * See if another thread got here after we tested it initially but
+         * before we got our lock.
+         */
+        if (need_func_call) {
+                /*
+                 * Nope, we still need to issue the call. Set the "once"
+                 * variable to true now so we can unlock the mutex. (We don't
+                 * want to leave it locked during the call to the
+                 * initialization function in case there's yet another "once"
+                 * function needed to be called from therein.)
+                 */
+                *ponce = true;
+        }
+
+        /* Unlock the mutex */
+	if ((ret = SMB_THREAD_LOCK(once_mutex, SMB_THREAD_UNLOCK)) != 0) {
+                smb_panic("error unlocking 'once'");
+	}
+
+        /* Finally, if we need to call the user-provided function, ... */
+        if (need_func_call) {
+                /* ... then do so now. */
+                (*init_fn)();
+        }
+}
+
+
 #if 0
 /* Test. - pthread implementations. */
 #include <pthread.h>
@@ -128,7 +190,7 @@ int test_threads(void)
 	if ((ret = SMB_THREAD_LOCK(plock, SMB_THREAD_LOCK)) != 0) {
 		printf("lock error: %d\n", ret);
 	}
-	if ((SMB_THREAD_LOCK(plock, SMB_THREAD_UNLOCK)) != 0) {
+	if ((ret = SMB_THREAD_LOCK(plock, SMB_THREAD_UNLOCK)) != 0) {
 		printf("unlock error: %d\n", ret);
 	}
 	SMB_THREAD_DESTROY_MUTEX(plock);
diff --git a/lib/util/smb_threads.h b/lib/util/smb_threads.h
index 4443c3e..012b61c 100644
--- a/lib/util/smb_threads.h
+++ b/lib/util/smb_threads.h
@@ -20,20 +20,10 @@
 #ifndef _smb_threads_h_
 #define _smb_threads_h_
 
-/* Data types needed for smb_thread_once call. */
-
-#if defined(HAVE_PTHREAD_H)
-#include <pthread.h>
-#define smb_thread_once_t pthread_once_t
-#define SMB_THREAD_ONCE_INIT PTHREAD_ONCE_INIT
-#define SMB_THREAD_ONCE_IS_INITIALIZED(val) (true)
-#define SMB_THREAD_ONCE_INITIALIZE(val)
-#else
-#define smb_thread_once_t bool
+typedef bool smb_thread_once_t;
 #define SMB_THREAD_ONCE_INIT false
 #define SMB_THREAD_ONCE_IS_INITIALIZED(val) ((val) == true)
 #define SMB_THREAD_ONCE_INITIALIZE(val) ((val) = true)
-#endif
 
 enum smb_thread_lock_type {
 	SMB_THREAD_LOCK = 1,
@@ -47,11 +37,9 @@ struct smb_thread_functions {
 			const char *location);
 	void (*destroy_mutex)(void *plock,
 			const char *location);
-	int (*lock_mutex)(void *plock, enum smb_thread_lock_type lock_type,
-			const char *location);
-
-	/* Once initialization. */
-	int (*smb_thread_once)(smb_thread_once_t *p_once, void (*init_fn)(void));
+	int (*lock_mutex)(void *plock,
+                          int lock_type,
+                          const char *location);
 
 	/* Thread local storage. */
 	int (*create_tls)(const char *keyname,
@@ -64,6 +52,7 @@ struct smb_thread_functions {
 };
 
 int smb_thread_set_functions(const struct smb_thread_functions *tf);
+void smb_thread_once(smb_thread_once_t *ponce, void (*init_fn)(void));
 
 extern const struct smb_thread_functions *global_tfp;
 
@@ -88,7 +77,7 @@ static void smb_destroy_mutex_pthread(void *plock, const char *location) \
 	free(plock); \
 } \
  \
-static int smb_lock_pthread(void *plock, enum smb_thread_lock_type lock_type, const char *location) \
+static int smb_lock_pthread(void *plock, int lock_type, const char *location) \
 { \
 	if (lock_type == SMB_THREAD_UNLOCK) { \
 		return pthread_mutex_unlock((pthread_mutex_t *)plock); \
@@ -97,11 +86,6 @@ static int smb_lock_pthread(void *plock, enum smb_thread_lock_type lock_type, co
 	} \
 } \
  \
-static int smb_thread_once_pthread(smb_thread_once_t *p_once, void (*init_fn)(void)) \
-{ \
-	return pthread_once(p_once, init_fn); \
-} \
- \
 static int smb_create_tls_pthread(const char *keyname, void **ppkey, const char *location) \
 { \
 	int ret; \
@@ -142,7 +126,6 @@ static const struct smb_thread_functions (tf) = { \
 			smb_create_mutex_pthread, \
 			smb_destroy_mutex_pthread, \
 			smb_lock_pthread, \
-			smb_thread_once_pthread, \
 			smb_create_tls_pthread, \
 			smb_destroy_tls_pthread, \
 			smb_set_tls_pthread, \
diff --git a/lib/util/smb_threads_internal.h b/lib/util/smb_threads_internal.h
index b7e862a..0260934 100644
--- a/lib/util/smb_threads_internal.h
+++ b/lib/util/smb_threads_internal.h
@@ -34,7 +34,7 @@
 	(global_tfp ? global_tfp->lock_mutex((plock), (type), __location__) : 0)
 
 #define SMB_THREAD_ONCE(ponce, init_fn) \
-	(global_tfp ? global_tfp->smb_thread_once((ponce), (init_fn)) : ((init_fn()), 0))
+	(global_tfp ? smb_thread_once((ponce), (init_fn)) : ((init_fn()), 0))
 
 #define SMB_THREAD_CREATE_TLS(keyname, key) \
 	(global_tfp ? global_tfp->create_tls((keyname), &(key), __location__) : 0)
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 40a2045..190560a 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -873,7 +873,9 @@ LIBSMBCLIENT_OBJ0 = \
 		    libsmb/libsmb_server.o \
 		    libsmb/libsmb_stat.o \
 		    libsmb/libsmb_xattr.o \
-		    libsmb/libsmb_setget.o
+		    libsmb/libsmb_setget.o \
+		    libsmb/libsmb_thread_impl.o \
+		    libsmb/libsmb_thread_posix.o
 
 LIBSMBCLIENT_OBJ1 = $(LIBSMBCLIENT_OBJ0) \
 		    $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h
index 869aeb6..3b38b30 100644
--- a/source3/include/libsmbclient.h
+++ b/source3/include/libsmbclient.h
@@ -2696,6 +2696,115 @@ smbc_set_credentials_with_fallback(SMBCCTX *ctx,
 			     	   const char *user,
 			    	   const char *password);
 
+
+/**
+ * @ingroup threads
+ *
+ * Initialize for threads using the Posix Threads (pthread)
+ * implementation. This is a built-in implementation, avoiding the need to
+ * implement the component functions of the thread interface. If this function
+ * is used, it is not necessary to call smbc_thread_impl().
+ *
+ * @return {void}
+ */
+void
+smbc_thread_posix(void);
+
+/**
+ * @ingroup threads
+ *
+ * Initialize for an arbitrary thread implementation. The caller should
+ * provide, as parameters, pointers to functions to implement the requisite
+ * low-level thread functionality. A function must be provided for each
+ * parameter; none may be null.
+ *
+ * If the thread implementation is POSIX Threads (pthreads), then the much
+ * simpler smbc_thread_pthread() function may be used instead of this one.
+ *
+ * @param create_mutex
+ *   Create a mutex. This function should expect three parameters: lockname,
+ *   pplock, and location. It should create a unique mutex for each unique
+ *   lockname it is provided, and return the mutex identifier in *pplock. The
+ *   location parameter can be used for debugging, as it contains the
+ *   compiler-provided __location__ of the call.
+ *
+ * @param destroy_mutex
+ *   Destroy a mutex. This function should expect two parameters: plock and
+ *   location. It should destroy the mutex associated with the identifier
+ *   plock. The location parameter can be used for debugging, as it contains
+ *   the compiler-provided __location__ of the call.
+ *
+ * @param lock_mutex
+ *   Lock a mutex. This function should expect three parameters: plock,
+ *   lock_type, and location. The mutex aassociated with identifier plock
+ *   should be locked if lock_type is 1, and unlocked if lock_type is 2. The
+ *   location parameter can be used for debugging, as it contains the
+ *   compiler-provided __location__ of the call.
+ *
+ * @param create_tls
+ *   Create thread local storage. This function should expect three
+ *   parameters: keyname, ppkey, and location. It should allocate an
+ *   implementation-specific amount of memory and assign the pointer to that
+ *   allocated memory to *ppkey. The location parameter can be used for
+ *   debugging, as it contains the compiler-provided __location__ of the
+ *   call. This function should return 0 upon success, non-zero upon failure.
+ *
+ * @param destroy_tls
+ *   Destroy thread local storage. This function should expect two parameters:
+ *   ppkey and location. The ppkey parameter points to a variable containing a
+ *   thread local storage key previously provided by the create_tls
+ *   function. The location parameter can be used for debugging, as it
+ *   contains the compiler-provided __location__ of the call.
+ *
+ * @param set_tls
+ *   Set a thread local storage variable's value. This function should expect
+ *   three parameters: pkey, pval, and location. The pkey parameter is a
+ *   thread local storage key previously provided by the create_tls
+ *   function. The (void *) pval parameter contains the value to be placed in
+ *   the thread local storage variable identified by pkey. The location
+ *   parameter can be used for debugging, as it contains the compiler-provided
+ *   __location__ of the call. This function should return 0 upon success;
+ *   non-zero otherwise.
+ *
+ * @param get_tls
+ *   Retrieve a thread local storage variable's value. This function should
+ *   expect two parameters: pkey and location. The pkey parameter is a thread
+ *   local storage key previously provided by the create_tls function, and
+ *   which has previously been used in a call to the set_tls function to
+ *   initialize a thread local storage variable. The location parameter can be
+ *   used for debugging, as it contains the compiler-provided __location__ of
+ *   the call. This function should return the (void *) value stored in the
+ *   variable identified by pkey.
+ *
+ * @return {void}
+ */
+void
+smbc_thread_impl(
+        /* Mutex functions. */
+        int (*create_mutex)(const char *lockname,
+                            void **pplock,
+                            const char *location);
+        void (*destroy_mutex)(void *plock,
+                              const char *location);
+        int (*lock_mutex)(void *plock,
+                          int lock_type,
+                          const char *location);
+    
+        /* Thread local storage. */
+        int (*create_tls)(const char *keyname,
+                          void **ppkey,
+                          const char *location);
+        void (*destroy_tls)(void **ppkey,
+                            const char *location);
+        int (*set_tls)(void *pkey,
+                       const void *pval,
+                       const char *location);
+        void *(*get_tls)(void *pkey,
+                         const char *location);
+        );
+
+
+
 /**
  * @ingroup structure
  * Structure that contains a client context information 
diff --git a/source3/libsmb/libsmb_thread_impl.c b/source3/libsmb/libsmb_thread_impl.c
new file mode 100644
index 0000000..c0ed636
--- /dev/null
+++ b/source3/libsmb/libsmb_thread_impl.c
@@ -0,0 +1,127 @@
+/* 
+   Unix SMB/Netbios implementation.
+   SMB client library implementation
+   Copyright (C) Derrell Lipman 2009
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "libsmbclient.h"
+#include "libsmb_internal.h"
+
+
+/**
+ * Initialize for an arbitrary thread implementation. The caller should
+ * provide, as parameters, pointers to functions to implement the requisite
+ * low-level thread functionality. A function must be provided for each
+ * parameter; none may be null.
+ *
+ * If the thread implementation is POSIX Threads (pthreads), then the much
+ * simpler smbc_thread_pthread() function may be used instead of this one.
+ *
+ * @param create_mutex
+ *   Create a mutex. This function should expect three parameters: lockname,
+ *   pplock, and location. It should create a unique mutex for each unique
+ *   lockname it is provided, and return the mutex identifier in *pplock. The
+ *   location parameter can be used for debugging, as it contains the
+ *   compiler-provided __location__ of the call.
+ *
+ * @param destroy_mutex
+ *   Destroy a mutex. This function should expect two parameters: plock and
+ *   location. It should destroy the mutex associated with the identifier
+ *   plock. The location parameter can be used for debugging, as it contains
+ *   the compiler-provided __location__ of the call.
+ *
+ * @param lock_mutex
+ *   Lock a mutex. This function should expect three parameters: plock,
+ *   lock_type, and location. The mutex aassociated with identifier plock
+ *   should be locked if lock_type is 1, and unlocked if lock_type is 2. The
+ *   location parameter can be used for debugging, as it contains the
+ *   compiler-provided __location__ of the call.
+ *
+ * @param create_tls
+ *   Create thread local storage. This function should expect three
+ *   parameters: keyname, ppkey, and location. It should allocate an
+ *   implementation-specific amount of memory and assign the pointer to that
+ *   allocated memory to *ppkey. The location parameter can be used for
+ *   debugging, as it contains the compiler-provided __location__ of the
+ *   call. This function should return 0 upon success, non-zero upon failure.
+ *
+ * @param destroy_tls
+ *   Destroy thread local storage. This function should expect two parameters:
+ *   ppkey and location. The ppkey parameter points to a variable containing a
+ *   thread local storage key previously provided by the create_tls
+ *   function. The location parameter can be used for debugging, as it
+ *   contains the compiler-provided __location__ of the call.
+ *
+ * @param set_tls
+ *   Set a thread local storage variable's value. This function should expect
+ *   three parameters: pkey, pval, and location. The pkey parameter is a
+ *   thread local storage key previously provided by the create_tls
+ *   function. The (void *) pval parameter contains the value to be placed in
+ *   the thread local storage variable identified by pkey. The location
+ *   parameter can be used for debugging, as it contains the compiler-provided
+ *   __location__ of the call. This function should return 0 upon success;
+ *   non-zero otherwise.
+ *
+ * @param get_tls
+ *   Retrieve a thread local storage variable's value. This function should
+ *   expect two parameters: pkey and location. The pkey parameter is a thread
+ *   local storage key previously provided by the create_tls function, and
+ *   which has previously been used in a call to the set_tls function to
+ *   initialize a thread local storage variable. The location parameter can be
+ *   used for debugging, as it contains the compiler-provided __location__ of
+ *   the call. This function should return the (void *) value stored in the
+ *   variable identified by pkey.
+ *
+ * @return {void}
+ */
+void
+smbc_thread_impl(
+        /* Mutex functions. */
+        int (*create_mutex)(const char *lockname,
+                            void **pplock,
+                            const char *location),
+        void (*destroy_mutex)(void *plock,
+                              const char *location),
+        int (*lock_mutex)(void *plock,
+                          int lock_type,
+                          const char *location),
+    
+        /* Thread local storage. */
+        int (*create_tls)(const char *keyname,
+                          void **ppkey,
+                          const char *location),
+        void (*destroy_tls)(void **ppkey,
+                            const char *location),
+        int (*set_tls)(void *pkey,
+                       const void *pval,
+                       const char *location),
+        void *(*get_tls)(void *pkey,
+                         const char *location)
+        )
+{
+        static struct smb_thread_functions tf;
+
+        tf.create_mutex  = create_mutex;
+        tf.destroy_mutex = destroy_mutex;
+        tf.lock_mutex    = lock_mutex;
+        tf.create_tls    = create_tls;
+        tf.destroy_tls   = destroy_tls;
+        tf.set_tls       = set_tls;
+        tf.get_tls       = get_tls;
+
+        smb_thread_set_functions(&tf);
+}
diff --git a/source3/libsmb/libsmb_thread_posix.c b/source3/libsmb/libsmb_thread_posix.c
new file mode 100644
index 0000000..411ffbd
--- /dev/null
+++ b/source3/libsmb/libsmb_thread_posix.c
@@ -0,0 +1,49 @@
+/* 
+   Unix SMB/Netbios implementation.
+   SMB client library implementation
+   Copyright (C) Derrell Lipman 2009
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <pthread.h>
+#include "includes.h"
+#include "libsmbclient.h"
+#include "libsmb_internal.h"
+
+
+/* Get rid of the malloc checker */
+#ifdef malloc
+#undef malloc
+#endif
+
+/*
+ * Define the functions which implement the pthread interface
+ */
+SMB_THREADS_DEF_PTHREAD_IMPLEMENTATION(tf);
+
+
+/**
+ * Initialize for threads using the Posix Threads (pthread)
+ * implementation. This is a built-in implementation, avoiding the need to
+ * implement the component functions of the thread interface. If this function
+ * is used, it is not necessary to call smbc_thread_impl().
+ *
+ * @return {void}


-- 
Samba Shared Repository


More information about the samba-cvs mailing list