Subject: Re: Threading problems
To: Bill Studenmund <firstname.lastname@example.org>
From: Eric Haszlakiewicz <email@example.com>
Date: 11/23/2004 14:58:54
On Tue, Nov 23, 2004 at 12:07:55PM -0800, Bill Studenmund wrote:
> We do this trick via weak aliasing of symbols. All these routines
> (look in lib/libc/thread-stub/thread-stub.c) have weak aliases to
> internal, do-little routines. Like the mutex lock & unlock routines map to
> the one you saw. libpthread, however, has strong symbols for all of these
> routines. So if libpthread is around at initial link (program launch),
> these libc calls point to routines in libpthread (that know how to handle
> mutexes, etc.). If not, they point to routines to ensure that libpthread
> didn't get dlopen()'d.
> The reason libc kills the program if libpthread gets loaded later is that
> there is no way libc's routines can recover. The lock & unlock routines
> point to code that doesn't know how to deal with mutexes. Even if we did
> magically change all of the calls in libc into ones that dealt with
> mutexes, mutexes and condvars didn't get initialized at startup. So there
> isn't anything for them to work on.
So why don't we initialize them then? I can see how we would want to
avoid taking the performance hit on locking for programs that don't need
it, but wouldn't the impact of initialization be much smaller?
I can imagine building programs like postgres, that use dlopen, with
a "might-use-pthread" setting that turns on the initialization code. Perhaps
the setting would be based on whether the program uses dlopen(), which
could be checked by ld.elf_so. If dlopen() is used and loads libpthread
then it'd have to swap the weak references, which I'm guessing only
ld.elf_so does now.