Date: Mon, 29 Mar 2004 20:22:37 -0800 From: Sean McNeil <sean@mcneil.com> To: "Jacques A. Vidrine" <nectar@FreeBSD.org> Cc: freebsd-current@FreeBSD.org Subject: Re: nss_ldap broken Message-ID: <1080620557.31373.13.camel@server.mcneil.com> In-Reply-To: <20040330034315.GC5998@madman.celabo.org> References: <20040330023247.GA5637@madman.celabo.org> <Pine.GSO.4.10.10403292214380.12734-100000@pcnet5.pcnet.com> <20040330034315.GC5998@madman.celabo.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 2004-03-29 at 19:43, 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? > > [...] > > 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) > Not only that, but libldap.so.2: liblber.so.2 => /usr/local/lib/liblber.so.2 (0x2818b000) libpthread.so.1 => /usr/lib/libpthread.so.1 (0x28197000) libsasl2.so.2 => /usr/local/lib/libsasl2.so.2 (0x281bb000) libssl.so.3 => /usr/lib/libssl.so.3 (0x281d0000) libcrypto.so.3 => /lib/libcrypto.so.3 (0x28201000) libc.so.5 => /lib/libc.so.5 (0x28080000) So it seems unlikely that we can make nss_ldap.so not pull in pthread. > > > 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? > There are many programs and libraries out there that are pulling in pthread just because they want to be thread-safe (just a guess). Of course there are also those libraries that actually use threads, but it is admirable to make any library thread-safe even if no threads are used. Back to the problem at hand, I still think the fix presented by Jacques will work thus far. If it is a threaded program, then pthread will not be unloaded by the module (ref count). If we had an nss_*.so.1 module that actually started up a thread, then we'd still be in trouble, however, as __isthreaded would be set to 1 and not reset to 0 when pthread is unloaded. In that case, perhaps just not doing the unlock in nss_atexit makes sense. As mentioned before, the program is going away so there is no harm in keeping it. Sean
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1080620557.31373.13.camel>