]> git.ipfire.org Git - thirdparty/libtool.git/commitdiff
According to Howard Chu <hyc@highlandsun.com>:
authorGary V. Vaughan <gary@gnu.org>
Thu, 22 Apr 2004 22:08:19 +0000 (22:08 +0000)
committerGary V. Vaughan <gary@gnu.org>
Thu, 22 Apr 2004 22:08:19 +0000 (22:08 +0000)
Applications should assume that the native dlopen is NOT
thread-safe, and take care of locking themselves. All application
calls into libltdl should thus be protected by the caller.

* libltdl/lt_mutex.c, libltdl/lt_mutex.h: Removed.
* libltdl/Makefile.am (pkginclude_HEADERS): Removed lt_mutex.h.
(libltdl_la_SOURCES): Removed lt_mutex.c and lt_mutex.h.
* libltdl/ltdl.h: Don't include lt_mutex.h.
* libltdl/lt__private.h (LT__MUTEX_GETERROR, LT__MUTEX_SETERROR)
(LT__MUTEX_SETERRORSTR): Renamed to...
(LT__GETERROR, LT__SETERROR, LT__SETERRORSTR): ...this.  Changed
all callers.
(LT__MUTEX_LOCK, LT__MUTEX_UNLOCK, lt_dlmutex_lock)
(lt_dlmutex_unlock, lt_dlmutex_seterror, lt_dlmutex_geterror):
Removed.  Changed all callers.
* doc/libtool.texi (Thread Saftey in libltdl):
* NEWS: Updated.

18 files changed:
ChangeLog
NEWS
config/config.guess
config/config.sub
doc/libtool.texi
libltdl/Makefile.am
libltdl/loader-dld_link.c
libltdl/loader-dlopen.c
libltdl/loader-dyld.c
libltdl/loader-load_add_on.c
libltdl/loader-loadlibrary.c
libltdl/loader-preopen.c
libltdl/loader-shl_load.c
libltdl/lt__private.h
libltdl/lt_error.c
libltdl/lt_error.h
libltdl/ltdl.c
libltdl/ltdl.h

index 04b1668eca310e5ce91f7ab334b47dd7ebd7041e..65d8f0361525fd2ed2bee997b90b9a38f4df323d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2004-04-22  Gary V. Vaughan  <gary@gnu.org>
+
+       According to Howard Chu <hyc@highlandsun.com>:
+       Applications should assume that the native dlopen is NOT
+       thread-safe, and take care of locking themselves. All application
+       calls into libltdl should thus be protected by the caller.
+
+       * libltdl/lt_mutex.c, libltdl/lt_mutex.h: Removed.
+       * libltdl/Makefile.am (pkginclude_HEADERS): Removed lt_mutex.h.
+       (libltdl_la_SOURCES): Removed lt_mutex.c and lt_mutex.h.
+       * libltdl/ltdl.h: Don't include lt_mutex.h.
+       * libltdl/lt__private.h (LT__MUTEX_GETERROR, LT__MUTEX_SETERROR)
+       (LT__MUTEX_SETERRORSTR): Renamed to...
+       (LT__GETERROR, LT__SETERROR, LT__SETERRORSTR): ...this.  Changed
+       all callers.
+       (LT__MUTEX_LOCK, LT__MUTEX_UNLOCK, lt_dlmutex_lock)
+       (lt_dlmutex_unlock, lt_dlmutex_seterror, lt_dlmutex_geterror):
+       Removed.  Changed all callers.
+       * doc/libtool.texi (Thread Saftey in libltdl):
+       * NEWS: Updated.
+
 2004-04-19  Gary V. Vaughan  <gary@gnu.org>
 
        * m4/libtool.m4 (_LT_LANG_CXX_CONFIG): Detect Intel C++ compiler
diff --git a/NEWS b/NEWS
index 6190b7be98a86083614ffe3a7f0a09127df3e30b..1d14e3dd7e1fc0d1f7a8de8a56534cf74352a950 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -40,6 +40,9 @@ New in 1.5b: 2004-??-??; CVS version 1.5a, Libtool team:
 * libltdl no longer loads shared libraries with global symbol resolution,
   this caused problems when the symbols were intended to be overriden further
   up the stack; it is also not recommended practice.
+* libltdl no longer tries to support multi-threaded programming with
+  lt_dlmutex_register(), which was unusable with POSIX threads anyway.
+  The symbols are deprecated but exported for backwards compatibility.
 * libltdl no longer uses lt_dlmalloc, lt_dlrealloc and lt_dlfree.  The symbols
   are still exported for backwards compatibility.
 * libltdl no longer supports pre-c89 compilers.  Some of the pre89 portability
index 61f2e4c60871b85734dd3dfcb9318531c3191ef0..e8c6fc0c33c53bdff623861c24afba20775adc7c 100755 (executable)
@@ -3,7 +3,7 @@
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 #   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
-timestamp='2003-10-20'
+timestamp='2004-01-05'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -1186,7 +1186,7 @@ EOF
     *:QNX:*:4*)
        echo i386-pc-qnx
        exit 0 ;;
-    NSR-[DGKLNPTVWY]:NONSTOP_KERNEL:*:*)
+    NSR-?:NONSTOP_KERNEL:*:*)
        echo nsr-tandem-nsk${UNAME_RELEASE}
        exit 0 ;;
     *:NonStop-UX:*:*)
index fac5195126e741a45b671736832c919b654cfcdc..463186dbfd6bfed73ffd84bfc728f2315fafcb03 100755 (executable)
@@ -3,7 +3,7 @@
 #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 #   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
-timestamp='2003-11-20'
+timestamp='2004-01-05'
 
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
@@ -380,6 +380,9 @@ case $basic_machine in
        amd64)
                basic_machine=x86_64-pc
                ;;
+       amd64-*)
+               basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
        amdahl)
                basic_machine=580-amdahl
                os=-sysv
index 07c8b13a4e9a90de6225093f7841c501b68e5f8a..9634c6d0090d83e3a94fb41f8dc2c30fcd34bf9e 100644 (file)
@@ -3254,51 +3254,22 @@ foo1_la_LDFLAGS = -module
 @node Thread Saftey in libltdl
 @section Using libtldl in a multi threaded environment
 
-Using the @code{lt_dlmutex_register()} function, and by providing some
-appropriate callback function definitions, libltdl can be used in a
-multi-threaded environment.
-
-@deftypefn {Type} void lt_dlmutex_lock (void)
-This is the type of a function pointer holding the address of a function
-which will be called at the start of parts of the libltdl implementation
-code which require a mutex lock.
-
-Because libltdl is inherantly recursive, it is important that the
-locking mechanism employed by these callback functions are reentrant, or
-else strange problems will occur.
-@end deftypefn
-
-@deftypefn {Type} void lt_dlmutex_unlock (void)
-The type of a matching unlock function.
-@end deftypefn
-
-@deftypefn {Type} void lt_dlmutex_seterror @w{(const char *@var{error});}
-Many of the functions in the libltdl @sc{api} have a special return
-value to indicate to the client that an error has occured.  Normally (in
-single threaded applications) a string describing that error can be
-retrieved from internal storage with @code{lt_dlerror()}.
-
-A function of this type must be registered with the library in order for
-it to work in a multi-threaded context.  The function should store any
-error message passed in thread local storage.
-@end deftypefn
-
-@deftypefn {Type} {const char *} lt_dlmutex_geterror (void)
-The type of a matching callback function to retrieve the last stored
-error message from thread local storage.
-
-When registered correctly this function will be used by
-@code{lt_dlerror())} from all threads to retrieve error messages for the
-client.
-@end deftypefn
-
-@deftypefn {Function} int lt_dlmutex_register (@w{lt_dlmutex_lock *@var{lock}}, @w{lt_dlmutex_unlock *@var{unlock}}, @w{lt_dlmutex_set_error *@var{seterror}}, @w{lt_dlmutex_geterror *@var{geterror})}
-Use this function to register one of each of function types described
-above in preparation for multi-threaded use of libltdl.  All arguments
-must be valid non-@code{NULL} function addresses, or else all
-@code{NULL} to return to single threaded operation.
-@end deftypefn
-
+Libltdl provides a wrapper around whatever dynamic run-time object
+loading mechanisms are provided by the host system, many of which are
+themselves not thread safe.  Consequently libltdl cannot itself be
+consistently thread safe.
+
+If you wish to use libltdl in a multithreaded environment, then you
+must mutex lock around libltdl calls, since they may in turn be calling
+non-thread-safe system calls on some target hosts.
+
+Some old releases of libtool provided a mutex locking API that was
+unusable with POSIX threads, so callers were forced to lock around all
+libltdl API calls anyway.  That mutex locking API was next to useless,
+and is not present in current releases.
+
+Some future release of libtool may provide a new POSIX thread
+compliant mutex locking API.
 
 @node User defined module data
 @section Data associated with loaded modules
index 5773bb26b654a7e19154a9b9ff8a389985ee752f..bfbf2595e40eb74f9896165217f770ce31915799 100644 (file)
@@ -26,7 +26,7 @@ pkgincludedir = $(includedir)/libltdl
 
 if INSTALL_LTDL
 include_HEADERS = ltdl.h
-pkginclude_HEADERS = lt_system.h lt_error.h lt_mutex.h
+pkginclude_HEADERS = lt_system.h lt_error.h
 lib_LTLIBRARIES = libltdl.la
 endif
 
@@ -40,7 +40,7 @@ CLEANFILES        = libltdl.la libltdlc.la
 
 libltdl_la_SOURCES  = ltdl.h ltdl.c \
                      loader-preopen.c \
-                     lt_error.h lt_error.c lt_mutex.h lt_mutex.c \
+                     lt_error.h lt_error.c \
                      lt__private.h lt__alloc.h lt__alloc.c \
                      lt__glibc.h argz.h lt__dirent.h \
                      lt_system.h
index d43b62217b16f1dd19cca8b2b33422e3b559ee16..93626f56094c36f946c5f06c8250ea1fcd0e364f 100644 (file)
@@ -41,7 +41,7 @@ sys_dld_open (lt_user_data loader_data, const char *filename)
 
   if (dld_link (filename) != 0)
     {
-      LT__MUTEX_SETERROR (CANNOT_OPEN);
+      LT__SETERROR (CANNOT_OPEN);
       FREE (module);
     }
 
@@ -55,7 +55,7 @@ sys_dld_close (lt_user_data loader_data, lt_module module)a
 
   if (dld_unlink_by_file ((char*)(module), 1) != 0)
     {
-      LT__MUTEX_SETERROR (CANNOT_CLOSE);
+      LT__SETERROR (CANNOT_CLOSE);
       ++errors;
     }
   else
@@ -73,7 +73,7 @@ sys_dld_sym (lt_user_data loader_data, lt_module module, const char *symbol)
 
   if (!address)
     {
-      LT__MUTEX_SETERROR (SYMBOL_NOT_FOUND);
+      LT__SETERROR (SYMBOL_NOT_FOUND);
     }
 
   return address;
index 38766f8bf87425fdf0da0d68a3fe63c9c00019b2..6589bc3d33f549ff2b3030f8a93c996b303fe6ed 100644 (file)
@@ -68,8 +68,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 #  define DLERROR(arg) LT__STRERROR (arg)
 #endif
 
-#define DL__MUTEX_SETERROR(errorcode) \
-       LT__MUTEX_SETERRORSTR (DLERROR (errorcode))
+#define DL__SETERROR(errorcode) \
+       LT__SETERRORSTR (DLERROR (errorcode))
 
 static lt_module
 sys_dl_open (lt_user_data loader_data, const char *filename)
@@ -78,7 +78,7 @@ sys_dl_open (lt_user_data loader_data, const char *filename)
 
   if (!module)
     {
-      DL__MUTEX_SETERROR (CANNOT_OPEN);
+      DL__SETERROR (CANNOT_OPEN);
     }
 
   return module;
@@ -91,7 +91,7 @@ sys_dl_close (lt_user_data loader_data, lt_module module)
 
   if (dlclose (module) != 0)
     {
-      DL__MUTEX_SETERROR (CANNOT_CLOSE);
+      DL__SETERROR (CANNOT_CLOSE);
       ++errors;
     }
 
@@ -105,7 +105,7 @@ sys_dl_sym (lt_user_data loader_data, lt_module module, const char *symbol)
 
   if (!address)
     {
-      DL__MUTEX_SETERROR (SYMBOL_NOT_FOUND);
+      DL__SETERROR (SYMBOL_NOT_FOUND);
     }
 
   return address;
index 7f12959857d3985755b7bf941d4ca903e449b3eb..8e29faa7a0bc1896d85dc0f88a7dd462a0d7794f 100644 (file)
@@ -109,8 +109,8 @@ static int dyld_cannot_close                                = 0;
 #  define LT__MAGIC    MH_CIGAM
 #endif
 
-#define DYLD__MUTEX_SETERROR(errorcode) \
-       LT__MUTEX_SETERRORSTR (lt__dylderror (errorcode))
+#define DYLD__SETERROR(errorcode) \
+       LT__SETERRORSTR (lt__dylderror (errorcode))
 
 /* Return the dyld error string, or the passed in error string if none. */
 static const char *
@@ -254,8 +254,6 @@ lt__sys_dyld_init (void)
 {
   int errors = 0;
 
-  LT__MUTEX_LOCK ();
-
   if (! dyld_cannot_close)
     {
       if (!_dyld_present ())
@@ -276,8 +274,6 @@ lt__sys_dyld_init (void)
        }
     }
 
-  LT__MUTEX_UNLOCK ();
-
   return errors;
 }
 
@@ -317,7 +313,7 @@ sys_dyld_open (lt_user_data loader_data, const char *filename)
 
   if (!module)
     {
-      DYLD__MUTEX_SETERROR (LT_ERROR_CANNOT_OPEN);
+      DYLD__SETERROR (LT_ERROR_CANNOT_OPEN);
     }
 
   return module;
@@ -334,7 +330,7 @@ sys_dyld_close (lt_user_data loader_data, lt_module module)
       int flags = 0;
       if (mh->magic == LT__MAGIC)
        {
-         DYLD__MUTEX_SETERROR(dyld_cannot_close);
+         DYLD__SETERROR(dyld_cannot_close);
          ++errors;
        }
       else
@@ -353,7 +349,7 @@ sys_dyld_close (lt_user_data loader_data, lt_module module)
 #endif
          if (!NSUnLinkModule (module, flags))
            {
-             DYLD__MUTEX_SETERROR (LT_ERROR_CANNOT_CLOSE);
+             DYLD__SETERROR (LT_ERROR_CANNOT_CLOSE);
              ++errors;
            }
        }
@@ -405,7 +401,7 @@ sys_dyld_sym (lt_user_data loader_data, lt_module module, const char *symbol)
 
   if (!nssym)
     {
-      LT__MUTEX_SETERRORSTR (saveError);
+      LT__SETERRORSTR (saveError);
     }
 
   return nssym ? NSAddressOfSymbol (nssym) : 0;
index ff27d9c447361c31268d042faa06bb59d6951981..cfe81508f3791f4b36eadd6d59852a49a5c35a2b 100644 (file)
@@ -51,7 +51,7 @@ sys_bedl_open (lt_user_data loader_data, const char *filename)
 
   if (image <= 0)
     {
-      LT__MUTEX_SETERROR (CANNOT_OPEN);
+      LT__SETERROR (CANNOT_OPEN);
       image = 0;
     }
 
@@ -65,7 +65,7 @@ sys_bedl_close (lt_user_data loader_data, lt_module module)
 
   if (unload_add_on ((image_id) module) != B_OK)
     {
-      LT__MUTEX_SETERROR (CANNOT_CLOSE);
+      LT__SETERROR (CANNOT_CLOSE);
       ++errors;
     }
 
@@ -80,7 +80,7 @@ sys_bedl_sym (lt_user_data loader_data, lt_module module, const char *symbol)
 
   if (get_image_symbol (image, symbol, B_SYMBOL_TYPE_ANY, address) != B_OK)
     {
-      LT__MUTEX_SETERROR (SYMBOL_NOT_FOUND);
+      LT__SETERROR (SYMBOL_NOT_FOUND);
       address = 0;
     }
 
index ab28797b1a4a4d0ef7d0261cb98925497a489a59..8e56e40d32ef99f4afad74e92842649ab0c9c638 100644 (file)
@@ -92,7 +92,6 @@ sys_wll_open (lt_user_data loader_data, const char *filename)
      We check whether LoadLibrary is returning a handle to
      an already loaded module, and simulate failure if we
      find one. */
-  LT__MUTEX_LOCK ();
   cur = handles;
   while (cur)
     {
@@ -109,11 +108,10 @@ sys_wll_open (lt_user_data loader_data, const char *filename)
 
       cur = cur->next;
   }
-  LT__MUTEX_UNLOCK ();
 
   if (cur || !module)
     {
-      LT__MUTEX_SETERROR (CANNOT_OPEN);
+      LT__SETERROR (CANNOT_OPEN);
       module = 0;
     }
 
@@ -127,7 +125,7 @@ sys_wll_close (lt_user_data loader_data, lt_module module)
 
   if (FreeLibrary(module) == 0)
     {
-      LT__MUTEX_SETERROR (CANNOT_CLOSE);
+      LT__SETERROR (CANNOT_CLOSE);
       ++errors;
     }
 
@@ -141,7 +139,7 @@ sys_wll_sym (lt_user_data loader_data, lt_module module,const char *symbol)
 
   if (!address)
     {
-      LT__MUTEX_SETERROR (SYMBOL_NOT_FOUND);
+      LT__SETERROR (SYMBOL_NOT_FOUND);
     }
 
   return address;
index 6d22bae2df2322b56accb3cab30c5b8b7bee8baf..9b312745ffdcf45592549d058ea82ee706c60f3a 100644 (file)
@@ -46,16 +46,12 @@ lt__presym_init (lt_user_data loader_data)
 {
   int errors = 0;
 
-  LT__MUTEX_LOCK ();
-
   preloaded_symbols = 0;
   if (default_preloaded_symbols)
     {
       errors = lt_dlpreload (default_preloaded_symbols);
     }
 
-  LT__MUTEX_UNLOCK ();
-
   return errors;
 }
 
@@ -64,8 +60,6 @@ presym_free_symlists (void)
 {
   lt_dlsymlists_t *lists;
 
-  LT__MUTEX_LOCK ();
-
   lists = preloaded_symbols;
   while (lists)
     {
@@ -76,8 +70,6 @@ presym_free_symlists (void)
     }
   preloaded_symbols = 0;
 
-  LT__MUTEX_UNLOCK ();
-
   return 0;
 }
 
@@ -88,8 +80,6 @@ lt__presym_add_symlist (const lt_dlsymlist *preloaded)
   lt_dlsymlists_t *lists;
   int             errors   = 0;
 
-  LT__MUTEX_LOCK ();
-
   lists = preloaded_symbols;
   while (lists)
     {
@@ -114,7 +104,6 @@ lt__presym_add_symlist (const lt_dlsymlist *preloaded)
     }
 
  done:
-  LT__MUTEX_UNLOCK ();
   return errors;
 }
 
@@ -124,12 +113,11 @@ presym_open (lt_user_data loader_data, const char *filename)
   lt_dlsymlists_t *lists;
   lt_module       module = (lt_module) 0;
 
-  LT__MUTEX_LOCK ();
   lists = preloaded_symbols;
 
   if (!lists)
     {
-      LT__MUTEX_SETERROR (NO_SYMBOLS);
+      LT__SETERROR (NO_SYMBOLS);
       goto done;
     }
 
@@ -159,10 +147,9 @@ presym_open (lt_user_data loader_data, const char *filename)
       lists = lists->next;
     }
 
-  LT__MUTEX_SETERROR (FILE_NOT_FOUND);
+  LT__SETERROR (FILE_NOT_FOUND);
 
  done:
-  LT__MUTEX_UNLOCK ();
   return module;
 }
 
@@ -190,7 +177,7 @@ presym_sym (lt_user_data loader_data, lt_module module, const char *symbol)
     ++syms;
   }
 
-  LT__MUTEX_SETERROR (SYMBOL_NOT_FOUND);
+  LT__SETERROR (SYMBOL_NOT_FOUND);
 
   return 0;
 }
@@ -220,12 +207,10 @@ lt_dlpreload (const lt_dlsymlist *preloaded)
     {
       presym_free_symlists();
 
-      LT__MUTEX_LOCK ();
       if (default_preloaded_symbols)
        {
          errors = lt_dlpreload (default_preloaded_symbols);
        }
-      LT__MUTEX_UNLOCK ();
     }
 
   return errors;
@@ -234,8 +219,6 @@ lt_dlpreload (const lt_dlsymlist *preloaded)
 int
 lt_dlpreload_default (const lt_dlsymlist *preloaded)
 {
-  LT__MUTEX_LOCK ();
   default_preloaded_symbols = preloaded;
-  LT__MUTEX_UNLOCK ();
   return 0;
 }
index 1dae52996ab73ff4049fdb92ed832678957811a6..e5eff3f35639e75faa99e5826c2217d2afacbcab 100644 (file)
@@ -100,7 +100,7 @@ sys_shl_open (lt_user_data loader_data, const char *filenam)
 
       if (!module)
        {
-         LT__MUTEX_SETERROR (CANNOT_OPEN);
+         LT__SETERROR (CANNOT_OPEN);
        }
     }
 
@@ -114,7 +114,7 @@ sys_shl_close (lt_user_data loader_data, lt_module module)
 
   if (module && (shl_unload ((shl_t) (module)) != 0))
     {
-      LT__MUTEX_SETERROR (CANNOT_CLOSE);
+      LT__SETERROR (CANNOT_CLOSE);
       ++errors;
     }
 
@@ -129,13 +129,13 @@ sys_shl_sym (lt_user_data loader_data, lt_module module, const char *symbol)
   /* sys_shl_open should never return a NULL module handle */
   if (module == (lt_module) 0)
   {
-    LT__MUTEX_SETERROR (INVALID_HANDLE);
+    LT__SETERROR (INVALID_HANDLE);
   }
   else if (!shl_findsym((shl_t*) &module, symbol, TYPE_UNDEFINED, &address))
     {
       if (!address)
        {
-         LT__MUTEX_SETERROR (SYMBOL_NOT_FOUND);
+         LT__SETERROR (SYMBOL_NOT_FOUND);
        }
     }
 
index dcf404ca1aaa9c0b1c9138067a17f36107f56922..ee7fe9fcec7ca7085caba684815efa44365addae 100644 (file)
@@ -97,39 +97,10 @@ static const char *lt__error_strings[] =
 
 #define LT__STRERROR(name)     lt__error_strings[LT_CONC(LT_ERROR_,name)]
 
+#define LT__GETERROR(lvalue)         (lvalue) = lt__last_error;
+#define LT__SETERRORSTR(errormsg)     lt__last_error = (errormsg)
+#define LT__SETERROR(errorcode)              LT__SETERRORSTR(LT__STRERROR(errorcode))
 
-
-/* --- MUTEX LOCKING --- */
-
-/* Macros to make it easier to run the lock functions only if they have
-   been registered.  The reason for the complicated lock macro is to
-   ensure that the stored error message from the last error is not
-   accidentally erased if the current function doesn't generate an
-   error of its own.  */
-
-#define LT__MUTEX_LOCK()                       LT_STMT_START { \
-       if (lt__mutex_lock_func) (*lt__mutex_lock_func)();      \
-                                               } LT_STMT_END
-#define LT__MUTEX_UNLOCK()                     LT_STMT_START { \
-       if (lt__mutex_unlock_func) (*lt__mutex_unlock_func)();\
-                                               } LT_STMT_END
-#define LT__MUTEX_SETERRORSTR(errormsg)                LT_STMT_START { \
-       if (lt__mutex_seterror_func)                            \
-               (*lt__mutex_seterror_func) (errormsg);          \
-       else    lt__last_error = (errormsg);    } LT_STMT_END
-#define LT__MUTEX_GETERROR(errormsg)           LT_STMT_START { \
-       if (lt__mutex_seterror_func)                            \
-               (errormsg) = (*lt__mutex_geterror_func) ();     \
-       else    (errormsg) = lt__last_error;    } LT_STMT_END
-#define LT__MUTEX_SETERROR(errorcode)                          \
-       LT__MUTEX_SETERRORSTR(LT__STRERROR(errorcode))
-
-/* The mutex functions stored here are global, and are necessarily the
-   same for all threads that wish to share access to libltdl.  */
-LT_SCOPE lt_dlmutex_lock       *lt__mutex_lock_func;
-LT_SCOPE lt_dlmutex_unlock     *lt__mutex_unlock_func;
-LT_SCOPE lt_dlmutex_seterror   *lt__mutex_seterror_func;
-LT_SCOPE lt_dlmutex_geterror   *lt__mutex_geterror_func;
 LT_SCOPE const char            *lt__last_error;
 
 LT_END_C_DECLS
index 599e4144e5ad3b8e71d2c2490e5aa0eb132d0c44..01a8d60f78aad373a704b77459745c832780ae19 100644 (file)
@@ -27,9 +27,10 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 */
 
 #include "lt_error.h"
-#include "lt_mutex.h"
 #include "lt__private.h"
 
+LT_GLOBAL_DATA const char      *lt__last_error = 0;
+
 static const char    **user_error_strings      = 0;
 static int             errorcount              = LT_ERROR_MAX;
 
@@ -42,8 +43,6 @@ lt_dladderror (const char *diagnostic)
 
   assert (diagnostic);
 
-  LT__MUTEX_LOCK ();
-
   errindex = errorcount - LT_ERROR_MAX;
   temp = REALLOC (const char *, user_error_strings, 1 + errindex);
   if (temp)
@@ -53,8 +52,6 @@ lt_dladderror (const char *diagnostic)
       result                           = errorcount++;
     }
 
-  LT__MUTEX_UNLOCK ();
-
   return result;
 }
 
@@ -63,26 +60,22 @@ lt_dlseterror (int errindex)
 {
   int          errors   = 0;
 
-  LT__MUTEX_LOCK ();
-
   if (errindex >= errorcount || errindex < 0)
     {
       /* Ack!  Error setting the error message! */
-      LT__MUTEX_SETERROR (INVALID_ERRORCODE);
+      LT__SETERROR (INVALID_ERRORCODE);
       ++errors;
     }
   else if (errindex < LT_ERROR_MAX)
     {
       /* No error setting the error message! */
-      LT__MUTEX_SETERRORSTR (lt__error_strings[errindex]);
+      LT__SETERRORSTR (lt__error_strings[errindex]);
     }
   else
     {
       /* No error setting the error message! */
-      LT__MUTEX_SETERRORSTR (user_error_strings[errindex - LT_ERROR_MAX]);
+      LT__SETERRORSTR (user_error_strings[errindex - LT_ERROR_MAX]);
     }
 
-  LT__MUTEX_UNLOCK ();
-
   return errors;
 }
index b250899603d67023829e35abc95607b37bcc6455..82d901843608dae7d67b743e844332ea45a98c26 100644 (file)
@@ -56,7 +56,7 @@ LT_BEGIN_C_DECLS
     LT_ERROR(INVALID_ERRORCODE,     "invalid errorcode")               \
     LT_ERROR(SHUTDOWN,             "library already shutdown")         \
     LT_ERROR(CLOSE_RESIDENT_MODULE, "can't close resident module")     \
-    LT_ERROR(INVALID_MUTEX_ARGS,    "invalid mutex handler registration") \
+    LT_ERROR(INVALID_MUTEX_ARGS,    "internal error (code withdrawn)") \
     LT_ERROR(INVALID_POSITION,     "invalid search path insert position")
 
 /* Enumerate the symbolic error names. */
index c685ba2d4c75d1de4766c73854003892e0600ec0..3ab2719d0d2db2f2d19c14d6f5e65c81e97171a1 100644 (file)
@@ -206,7 +206,7 @@ static      int             initialized     = 0;
 void
 lt__alloc_die_callback (void)
 {
-  LT__MUTEX_SETERROR (NO_MEMORY);
+  LT__SETERROR (NO_MEMORY);
 }
 
 /* Initialize libltdl. */
@@ -215,8 +215,6 @@ lt_dlinit (void)
 {
   int        errors   = 0;
 
-  LT__MUTEX_LOCK ();
-
   /* Initialize only at first call. */
   if (++initialized == 1)
     {
@@ -254,18 +252,16 @@ lt_dlinit (void)
 
       if (lt__presym_init (lt__presym.dlloader_data))
        {
-         LT__MUTEX_SETERROR (INIT_LOADER);
+         LT__SETERROR (INIT_LOADER);
          ++errors;
        }
       else if (errors != 0)
        {
-         LT__MUTEX_SETERROR (DLOPEN_NOT_SUPPORTED);
+         LT__SETERROR (DLOPEN_NOT_SUPPORTED);
          ++errors;
        }
     }
 
-  LT__MUTEX_UNLOCK ();
-
   return errors;
 }
 
@@ -276,12 +272,11 @@ lt_dlexit (void)
   lt_dlloader *loader;
   int         errors   = 0;
 
-  LT__MUTEX_LOCK ();
   loader = loaders;
 
   if (!initialized)
     {
-      LT__MUTEX_SETERROR (SHUTDOWN);
+      LT__SETERROR (SHUTDOWN);
       ++errors;
       goto done;
     }
@@ -337,7 +332,6 @@ lt_dlexit (void)
     }
 
  done:
-  LT__MUTEX_UNLOCK ();
   return errors;
 }
 
@@ -349,8 +343,7 @@ tryall_dlopen (lt_dlhandle *handle, const char *filename)
   const char   *saved_error;
   int           errors         = 0;
 
-  LT__MUTEX_GETERROR (saved_error);
-  LT__MUTEX_LOCK ();
+  LT__GETERROR (saved_error);
 
   cur   = handles;
   loader = loaders;
@@ -390,7 +383,7 @@ tryall_dlopen (lt_dlhandle *handle, const char *filename)
         file_not_found() can detect what happened.
       if (access (filename, R_OK) != 0)
        {
-         LT__MUTEX_SETERROR (FILE_NOT_FOUND);
+         LT__SETERROR (FILE_NOT_FOUND);
          ++errors;
          goto done;
        } */
@@ -428,11 +421,9 @@ tryall_dlopen (lt_dlhandle *handle, const char *filename)
     }
 
   cur->loader  = loader;
-  LT__MUTEX_SETERRORSTR (saved_error);
+  LT__SETERRORSTR (saved_error);
 
  done:
-  LT__MUTEX_UNLOCK ();
-
   return errors;
 }
 
@@ -601,10 +592,10 @@ argzize_path (const char *path, char **pargz, size_t *pargz_len)
       switch (error)
        {
        case ENOMEM:
-         LT__MUTEX_SETERROR (NO_MEMORY);
+         LT__SETERROR (NO_MEMORY);
          break;
        default:
-         LT__MUTEX_SETERROR (UNKNOWN);
+         LT__SETERROR (UNKNOWN);
          break;
        }
 
@@ -630,11 +621,9 @@ foreach_dirinpath (const char *search_path, const char *base_name,
   char *filename       = 0;
   char *canonical      = 0;
 
-  LT__MUTEX_LOCK ();
-
   if (!search_path || !*search_path)
     {
-      LT__MUTEX_SETERROR (FILE_NOT_FOUND);
+      LT__SETERROR (FILE_NOT_FOUND);
       goto cleanup;
     }
 
@@ -681,8 +670,6 @@ foreach_dirinpath (const char *search_path, const char *base_name,
   FREE (canonical);
   FREE (filename);
 
-  LT__MUTEX_UNLOCK ();
-
   return result;
 }
 
@@ -779,7 +766,6 @@ load_deplibs (lt_dlhandle handle, char *deplibs)
     }
   ++errors;
 
-  LT__MUTEX_LOCK ();
   if (user_search_path)
     {
       save_search_path = lt__strdup (user_search_path);
@@ -825,8 +811,6 @@ load_deplibs (lt_dlhandle handle, char *deplibs)
   /* restore the old search path */
   MEMREASSIGN (user_search_path, save_search_path);
 
-  LT__MUTEX_UNLOCK ();
-
   if (!depcount)
     {
       errors = 0;
@@ -982,7 +966,7 @@ try_dlopen (lt_dlhandle *phandle, const char *filename)
   assert (phandle);
   assert (*phandle == 0);
 
-  LT__MUTEX_GETERROR (saved_error);
+  LT__GETERROR (saved_error);
 
   /* dlopen self? */
   if (!filename)
@@ -1091,11 +1075,9 @@ try_dlopen (lt_dlhandle *phandle, const char *filename)
        {
          const char *search_path;
 
-         LT__MUTEX_LOCK ();
          search_path = user_search_path;
          if (search_path)
            file = find_file (user_search_path, base_name, &dir);
-         LT__MUTEX_UNLOCK ();
 
          if (!file)
            {
@@ -1128,7 +1110,7 @@ try_dlopen (lt_dlhandle *phandle, const char *filename)
         the status flag, and bail out.  */
       if (!file)
        {
-         LT__MUTEX_SETERROR (FILE_NOT_FOUND);
+         LT__SETERROR (FILE_NOT_FOUND);
          ++errors;
          goto cleanup;
        }
@@ -1338,13 +1320,11 @@ try_dlopen (lt_dlhandle *phandle, const char *filename)
       (*phandle)->info.ref_count       = 1;
       MEMREASSIGN ((*phandle)->info.name, name);
 
-      LT__MUTEX_LOCK ();
       (*phandle)->next         = handles;
       handles                  = *phandle;
-      LT__MUTEX_UNLOCK ();
     }
 
-  LT__MUTEX_SETERRORSTR (saved_error);
+  LT__SETERRORSTR (saved_error);
 
  cleanup:
   FREE (dir);
@@ -1374,7 +1354,7 @@ file_not_found (void)
 {
   const char *error = 0;
 
-  LT__MUTEX_GETERROR (error);
+  LT__GETERROR (error);
   if (error == LT__STRERROR (FILE_NOT_FOUND))
     return 1;
 
@@ -1465,7 +1445,7 @@ lt_dlopenext (const char *filename)
 
   /* Still here?  Then we really did fail to locate any of the file
      names we tried.  */
-  LT__MUTEX_SETERROR (FILE_NOT_FOUND);
+  LT__SETERROR (FILE_NOT_FOUND);
   FREE (tmp);
   return 0;
 }
@@ -1482,10 +1462,10 @@ lt_argz_insert (char **pargz, size_t *pargz_len, char *before,
       switch (error)
        {
        case ENOMEM:
-         LT__MUTEX_SETERROR (NO_MEMORY);
+         LT__SETERROR (NO_MEMORY);
          break;
        default:
-         LT__MUTEX_SETERROR (UNKNOWN);
+         LT__SETERROR (UNKNOWN);
          break;
        }
       return 1;
@@ -1698,8 +1678,6 @@ lt_dlclose (lt_dlhandle handle)
   lt_dlhandle cur, last;
   int errors = 0;
 
-  LT__MUTEX_LOCK ();
-
   /* check whether the handle is valid */
   last = cur = handles;
   while (cur && handle != cur)
@@ -1710,7 +1688,7 @@ lt_dlclose (lt_dlhandle handle)
 
   if (!cur)
     {
-      LT__MUTEX_SETERROR (INVALID_HANDLE);
+      LT__SETERROR (INVALID_HANDLE);
       ++errors;
       goto done;
     }
@@ -1749,13 +1727,11 @@ lt_dlclose (lt_dlhandle handle)
 
   if (LT_DLIS_RESIDENT (handle))
     {
-      LT__MUTEX_SETERROR (CLOSE_RESIDENT_MODULE);
+      LT__SETERROR (CLOSE_RESIDENT_MODULE);
       ++errors;
     }
 
  done:
-  LT__MUTEX_UNLOCK ();
-
   return errors;
 }
 
@@ -1770,13 +1746,13 @@ lt_dlsym (lt_dlhandle handle, const char *symbol)
 
   if (!handle)
     {
-      LT__MUTEX_SETERROR (INVALID_HANDLE);
+      LT__SETERROR (INVALID_HANDLE);
       return 0;
     }
 
   if (!symbol)
     {
-      LT__MUTEX_SETERROR (SYMBOL_NOT_FOUND);
+      LT__SETERROR (SYMBOL_NOT_FOUND);
       return 0;
     }
 
@@ -1792,7 +1768,7 @@ lt_dlsym (lt_dlhandle handle, const char *symbol)
       sym = MALLOC (char, lensym + LT_SYMBOL_OVERHEAD + 1);
       if (!sym)
        {
-         LT__MUTEX_SETERROR (BUFFER_OVERFLOW);
+         LT__SETERROR (BUFFER_OVERFLOW);
          return 0;
        }
     }
@@ -1802,7 +1778,7 @@ lt_dlsym (lt_dlhandle handle, const char *symbol)
     {
       const char *saved_error;
 
-      LT__MUTEX_GETERROR (saved_error);
+      LT__GETERROR (saved_error);
 
       /* this is a libtool module */
       if (handle->loader->sym_prefix)
@@ -1828,7 +1804,7 @@ lt_dlsym (lt_dlhandle handle, const char *symbol)
            }
          return address;
        }
-      LT__MUTEX_SETERRORSTR (saved_error);
+      LT__SETERRORSTR (saved_error);
     }
 
   /* otherwise try "symbol" */
@@ -1856,8 +1832,8 @@ lt_dlerror (void)
 {
   const char *error;
 
-  LT__MUTEX_GETERROR (error);
-  LT__MUTEX_SETERRORSTR (0);
+  LT__GETERROR (error);
+  LT__SETERRORSTR (0);
 
   return error ? error : NULL;
 }
@@ -1938,10 +1914,8 @@ lt_dladdsearchdir (const char *search_dir)
 
   if (search_dir && *search_dir)
     {
-      LT__MUTEX_LOCK ();
       if (lt_dlpath_insertdir (&user_search_path, 0, search_dir) != 0)
        ++errors;
-      LT__MUTEX_UNLOCK ();
     }
 
   return errors;
@@ -1954,26 +1928,21 @@ lt_dlinsertsearchdir (const char *before, const char *search_dir)
 
   if (before)
     {
-      LT__MUTEX_LOCK ();
       if ((before < user_search_path)
          || (before >= user_search_path + LT_STRLEN (user_search_path)))
        {
-         LT__MUTEX_UNLOCK ();
-         LT__MUTEX_SETERROR (INVALID_POSITION);
+         LT__SETERROR (INVALID_POSITION);
          return 1;
        }
-      LT__MUTEX_UNLOCK ();
     }
 
   if (search_dir && *search_dir)
     {
-      LT__MUTEX_LOCK ();
       if (lt_dlpath_insertdir (&user_search_path,
                               (char *) before, search_dir) != 0)
        {
          ++errors;
        }
-      LT__MUTEX_UNLOCK ();
     }
 
   return errors;
@@ -1984,19 +1953,15 @@ lt_dlsetsearchpath (const char *search_path)
 {
   int   errors     = 0;
 
-  LT__MUTEX_LOCK ();
   FREE (user_search_path);
-  LT__MUTEX_UNLOCK ();
 
   if (!search_path || !LT_STRLEN (search_path))
     {
       return errors;
     }
 
-  LT__MUTEX_LOCK ();
   if (canonicalize_path (search_path, &user_search_path) != 0)
     ++errors;
-  LT__MUTEX_UNLOCK ();
 
   return errors;
 }
@@ -2006,9 +1971,7 @@ lt_dlgetsearchpath (void)
 {
   const char *saved_path;
 
-  LT__MUTEX_LOCK ();
   saved_path = user_search_path;
-  LT__MUTEX_UNLOCK ();
 
   return saved_path;
 }
@@ -2020,7 +1983,7 @@ lt_dlmakeresident (lt_dlhandle handle)
 
   if (!handle)
     {
-      LT__MUTEX_SETERROR (INVALID_HANDLE);
+      LT__SETERROR (INVALID_HANDLE);
       ++errors;
     }
   else
@@ -2036,7 +1999,7 @@ lt_dlisresident   (lt_dlhandle handle)
 {
   if (!handle)
     {
-      LT__MUTEX_SETERROR (INVALID_HANDLE);
+      LT__SETERROR (INVALID_HANDLE);
       return -1;
     }
 
@@ -2053,7 +2016,7 @@ lt_dlgetinfo (lt_dlhandle handle)
 {
   if (!handle)
     {
-      LT__MUTEX_SETERROR (INVALID_HANDLE);
+      LT__SETERROR (INVALID_HANDLE);
       return 0;
     }
 
@@ -2090,8 +2053,6 @@ lt_dlforeach (int (*func) (lt_dlhandle handle, void *data), void *data)
   int errors = 0;
   lt_dlhandle cur;
 
-  LT__MUTEX_LOCK ();
-
   cur = handles;
   while (cur)
     {
@@ -2105,8 +2066,6 @@ lt_dlforeach (int (*func) (lt_dlhandle handle, void *data), void *data)
        }
     }
 
-  LT__MUTEX_UNLOCK ();
-
   return errors;
 }
 
@@ -2114,13 +2073,7 @@ lt_dlcaller_id
 lt_dlcaller_register (void)
 {
   static lt_dlcaller_id last_caller_id = 0;
-  int result;
-
-  LT__MUTEX_LOCK ();
-  result = ++last_caller_id;
-  LT__MUTEX_UNLOCK ();
-
-  return result;
+  return ++last_caller_id;
 }
 
 void *
@@ -2130,10 +2083,6 @@ lt_dlcaller_set_data (lt_dlcaller_id key, lt_dlhandle handle, void *data)
   void *stale = (void *) 0;
   int i;
 
-  /* This needs to be locked so that the caller data can be updated
-     simultaneously by different threads.  */
-  LT__MUTEX_LOCK ();
-
   if (handle->caller_data)
     while (handle->caller_data[n_elements].key)
       ++n_elements;
@@ -2170,8 +2119,6 @@ lt_dlcaller_set_data (lt_dlcaller_id key, lt_dlhandle handle, void *data)
   handle->caller_data[i].data = data;
 
  done:
-  LT__MUTEX_UNLOCK ();
-
   return stale;
 }
 
@@ -2180,10 +2127,6 @@ lt_dlcaller_get_data  (lt_dlcaller_id key, lt_dlhandle handle)
 {
   void *result = (void *) 0;
 
-  /* This needs to be locked so that the caller data isn't updated by
-     another thread part way through this function.  */
-  LT__MUTEX_LOCK ();
-
   /* Locate the index of the element with a matching KEY.  */
   {
     int i;
@@ -2197,8 +2140,6 @@ lt_dlcaller_get_data  (lt_dlcaller_id key, lt_dlhandle handle)
       }
   }
 
-  LT__MUTEX_UNLOCK ();
-
   return result;
 }
 
@@ -2219,7 +2160,7 @@ lt_dlloader_add (lt_dlloader *place, const struct lt_user_dlloader *dlloader,
       || (dlloader->module_close == 0)
       || (dlloader->find_sym == 0))
     {
-      LT__MUTEX_SETERROR (INVALID_LOADER);
+      LT__SETERROR (INVALID_LOADER);
       return 1;
     }
 
@@ -2237,7 +2178,6 @@ lt_dlloader_add (lt_dlloader *place, const struct lt_user_dlloader *dlloader,
   node->find_sym       = dlloader->find_sym;
   node->dlloader_data  = dlloader->dlloader_data;
 
-  LT__MUTEX_LOCK ();
   if (!loaders)
     {
       /* If there are no loaders, NODE becomes the list! */
@@ -2270,7 +2210,7 @@ lt_dlloader_add (lt_dlloader *place, const struct lt_user_dlloader *dlloader,
 
       if (ptr->next != place)
        {
-         LT__MUTEX_SETERROR (INVALID_LOADER);
+         LT__SETERROR (INVALID_LOADER);
          ++errors;
        }
       else
@@ -2281,8 +2221,6 @@ lt_dlloader_add (lt_dlloader *place, const struct lt_user_dlloader *dlloader,
        }
     }
 
-  LT__MUTEX_UNLOCK ();
-
   return errors;
 }
 
@@ -2295,20 +2233,17 @@ lt_dlloader_remove (const char *loader_name)
 
   if (!place)
     {
-      LT__MUTEX_SETERROR (INVALID_LOADER);
+      LT__SETERROR (INVALID_LOADER);
       return 1;
     }
 
-  LT__MUTEX_LOCK ();
-
   /* Fail if there are any open modules which use this loader. */
   for  (handle = handles; handle; handle = handle->next)
     {
       if (handle->loader == place)
        {
-         LT__MUTEX_SETERROR (REMOVE_LOADER);
-         ++errors;
-         goto done;
+         LT__SETERROR (REMOVE_LOADER);
+         return ++errors;
        }
     }
 
@@ -2340,22 +2275,13 @@ lt_dlloader_remove (const char *loader_name)
 
   FREE (place);
 
- done:
-  LT__MUTEX_UNLOCK ();
-
   return errors;
 }
 
 lt_dlloader *
 lt_dlloader_next (lt_dlloader *place)
 {
-  lt_dlloader *next;
-
-  LT__MUTEX_LOCK ();
-  next = place ? place->next : loaders;
-  LT__MUTEX_UNLOCK ();
-
-  return next;
+  return place ? place->next : loaders;
 }
 
 const char *
@@ -2365,13 +2291,11 @@ lt_dlloader_name (lt_dlloader *place)
 
   if (place)
     {
-      LT__MUTEX_LOCK ();
       name = place ? place->loader_name : 0;
-      LT__MUTEX_UNLOCK ();
     }
   else
     {
-      LT__MUTEX_SETERROR (INVALID_LOADER);
+      LT__SETERROR (INVALID_LOADER);
     }
 
   return name;
@@ -2384,13 +2308,11 @@ lt_dlloader_data (lt_dlloader *place)
 
   if (place)
     {
-      LT__MUTEX_LOCK ();
       data = place ? &(place->dlloader_data) : 0;
-      LT__MUTEX_UNLOCK ();
     }
   else
     {
-      LT__MUTEX_SETERROR (INVALID_LOADER);
+      LT__SETERROR (INVALID_LOADER);
     }
 
   return data;
@@ -2401,7 +2323,6 @@ lt_dlloader_find (const char *loader_name)
 {
   lt_dlloader *place = 0;
 
-  LT__MUTEX_LOCK ();
   for (place = loaders; place; place = place->next)
     {
       if (strcmp (place->loader_name, loader_name) == 0)
@@ -2409,7 +2330,6 @@ lt_dlloader_find (const char *loader_name)
          break;
        }
     }
-  LT__MUTEX_UNLOCK ();
 
   return place;
 }
@@ -2417,8 +2337,24 @@ lt_dlloader_find (const char *loader_name)
 
 
 \f
-/* These pointers are part of the published interface to libltdl,
+/* These symbols are part of the published interface to libltdl,
    although they are no longer used.  */
 LT_GLOBAL_DATA void *(*lt_dlmalloc)    (size_t size) = 0;
 LT_GLOBAL_DATA void *(*lt_dlrealloc)   (void *ptr, size_t size) = 0;
 LT_GLOBAL_DATA void  (*lt_dlfree)      (void *ptr) = 0;
+
+/*ARGSUSED*/
+int
+lt_dlmutex_register (lt_dlmutex_lock *lock, lt_dlmutex_unlock *unlock,
+                    lt_dlmutex_seterror *seterror,
+                    lt_dlmutex_geterror *geterror)
+{
+  static int warned = 0;
+
+  if (warned++ == 0)
+    {
+      fputs ("libltdl: WARNING: lt_dlmutex_register() is deprecated.\n"
+            "libltdl: WARNING: this version of libltdl is not thread safe.\n",
+            stderr);
+    }
+}
index 3e93a83767149a150fd641b30c8d2db4dbbc4576..fcf076b520ba07c746624cdcde15cc0407f67c11 100644 (file)
@@ -32,7 +32,6 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 
 #include <libltdl/lt_system.h>
 #include <libltdl/lt_error.h>
-#include <libltdl/lt_mutex.h>
 
 LT_BEGIN_C_DECLS
 
@@ -128,10 +127,21 @@ LT_SCOPE void *           lt_dlcaller_get_data  (lt_dlcaller_id key,
 \f
 /* --- BINARY COMPATIBILITY WITH OLD LIBLTDL --- */
 
+typedef void   lt_dlmutex_lock         (void);
+typedef void   lt_dlmutex_unlock       (void);
+typedef void   lt_dlmutex_seterror     (const char *errmsg);
+typedef const char *lt_dlmutex_geterror        (void);
+
 LT_SCOPE void * (*lt_dlmalloc) (size_t size);
 LT_SCOPE void * (*lt_dlrealloc)        (void *ptr, size_t size);
 LT_SCOPE void  (*lt_dlfree)    (void *ptr);
 
+
+LT_SCOPE int   lt_dlmutex_register     (lt_dlmutex_lock *lock,
+                                        lt_dlmutex_unlock *unlock,
+                                        lt_dlmutex_seterror *seterror,
+                                        lt_dlmutex_geterror *geterror);
+
 # define lt_ptr                void *