Re: nss_ldap broken

From: Daniel Eischen <eischen_at_vigrid.com>
Date: Tue, 30 Mar 2004 01:17:56 -0500 (EST)
On Mon, 29 Mar 2004, Jacques A. Vidrine wrote:

> On Mon, Mar 29, 2004 at 10:31:56PM -0500, Daniel Eischen wrote:
> > On Mon, 29 Mar 2004, Jacques A. Vidrine wrote:
> > 
> > > On Fri, Mar 26, 2004 at 05:51:02PM -0500, Daniel Eischen wrote:
> > > > I think I made a comment about how you should always
> > > > prefix _pthread_foo() calls with 'if (__isthreaded)'.
> > > 
> > > Yes, I'm sure you did.  My recollection was that it was an
> > > optimization only, but it seems either I misunderstood or my
> > > recollection is poor (or both) :-)
> > 
> > I had no idea that libpthread would be loaded then unloaded.
> 
> Me neither :-)
> 
> > >  (2)  When a threading library is loaded (by any cause? DT_NEEDED?
> > >       dlopen RTLD_GLOBAL? dlopen RTLD_LOCAL?), __isthreaded is set
> > >       to 1
> > 
> > No, __isthreaded is only set to 1 (non-zero) when the first
> > thread (other than main) is created.  But the library is
> > auto-initialized and that's when libc's jump table is
> > filled.
> 
> Gotcha, thanks for the clarification.
> 
> > >  (3)  When a threading library is unloaded, __isthreaded is reset to 0
> > 
> > No, once threaded always threaded.  There's really no going
> > back.
> 
> So e.g. dlopen(libpthread) ... dlclose(libpthread) is not supported?
> 
> And following from that, dlopen(object_which_depends_on_libpthread) ...
> dlclose(object_which_depends_on_libpthread) may also not be supported?

No, not with the jump tables in libc.  You'd have to somehow
know that libpthread was being unloaded and then revert the
jump tables back to their prior value.

> [...]
> > I'm unsure how nss_ldap was built to depend on libpthread (or
> > any threads library).  I built it from ports and 'ldd' didn't
> > report any dependency on a threads library.
> 
> Interesting.  Rebuilt a few days ago after updating to OpenLDAP 2.1:
> 
> % ldd /usr/local/lib/nss_ldap.so.1
> /usr/local/lib/nss_ldap.so.1:
>         libldap.so.2 => /usr/local/lib/libldap.so.2 (0x2815f000)
>         liblber.so.2 => /usr/local/lib/liblber.so.2 (0x28189000)
>         libpthread.so.1 => /usr/lib/libpthread.so.1 (0x28194000)
>         libssl.so.3 => /usr/lib/libssl.so.3 (0x281b7000)
>         libcrypto.so.3 => /lib/libcrypto.so.3 (0x281e4000)

Weird, I didn't get that.  My ports tree was a few weeks
old, though.

> > An example of how to build a library that is thread-safe
> > but doesn't bring in the threads library is libgcc.  It uses
> > weak references (not definitions, like you see in our libc
> > and libpthread) to the necessary locking functions and
> > pthread_create.  For instance:
> > 
> > 	#pragma weak	pthread_create
> > 	#pragma weak	pthread_mutex_lock
> > 	#pragma weak	pthread_mutex_unlock
> > 	...
> > 
> > 	static void
> > 	foo(void)
> > 	{
> > 		...
> > 		if (pthread_create != NULL) {
> > 			pthread_mutex_lock(&foo_lock);
> > 			...
> > 			pthread_mutex_unlock(&foo_lock);
> > 		}
> > 		...
> > 	}
> > 
> > By making the pthread_* references weak, you don't need to be linked
> > to the threads library; they will be NULL if it is not present.
> > But if an application is linked to the threads library, then
> > those references won't be NULL.  There may be a little more
> > fu to it, but that's the general idea.
> 
> Huh.  Can/Should something like this be hidden within <pthread.h>, I
> wonder?

No, you still want applications to pull in the pthread_*
references.  But something like that would be good for
nss_ldap or other libraries that want to be thread-safe
but yet don't want to unnecessarily pull in the threads
library.

-- 
Dan Eischen
Received on Mon Mar 29 2004 - 20:17:58 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:49 UTC