Making a library thread-safe

Making a library thread-safe

Post by Frank Jense » Tue, 28 Jan 2003 23:57:23



Hello,

I have been assigned the task of making a library thread-safe.  I'm
seeking advice on the following issues:

1) Sun's "Multithreaded Programming Guide" states that modules of a
multi-threaded application should be compiled with either -D_REENTRANT
or -D_POSIX_C_SOURCE=199506L (or both).  To get a single-threaded
application, none of these flags should be defined.  Page 167 of the
May 2002 version of this guide says: "This applies to every module of
an application."

Does this imply that it is impossible to create a single thread-safe
version of the library that can be linked into both single-threaded
and multi-threaded applications?

[I would prefer to not have to create two or perhaps four versions of
the library for each possible combination of the above mentioned
flags.]

2) The library has an error code global variable, much like `errno' in
the Standard C library.  This error code variable must somehow be
converted into thread-specific data.

The nicest solution would be to use thread-local storage (TLS), with
support from the linker, thread-library, compiler, and assembler.  The
Solaris 9 12/02 "Linker and Libraries Guide" suggests that the linker
supports TLS, but I cannot find anything about how to use this from
within C source code.

Perhaps this feature is not quite ready for use yet?

Otherwise, I suppose I must use the pthread_key_create,
pthread_setspecific, and pthread_getspecific functions?  And the key
must be created using a pthread_once_t control unless the user is
required to create the key explicitly?

Thanks in advance for any advice on these questions.

---

Hugin Expert A/S
Niels Jernes Vej 10
9220 Aalborg East
DENMARK

 
 
 

Making a library thread-safe

Post by Casper H.S. Di » Wed, 29 Jan 2003 01:35:49



>1) Sun's "Multithreaded Programming Guide" states that modules of a
>multi-threaded application should be compiled with either -D_REENTRANT
>or -D_POSIX_C_SOURCE=199506L (or both).  To get a single-threaded
>application, none of these flags should be defined.  Page 167 of the
>May 2002 version of this guide says: "This applies to every module of
>an application."
>Does this imply that it is impossible to create a single thread-safe
>version of the library that can be linked into both single-threaded
>and multi-threaded applications?

No, all system libraries are both thread safe and can be linked
by single threaded apps.

Quote:>[I would prefer to not have to create two or perhaps four versions of
>the library for each possible combination of the above mentioned
>flags.]

Compile it with -D_REENTRANT (but do not link the library with -lpthread)
Also, make sure the library is self-contained [i.e., link it with libc
and all other libraries it needs]

Quote:>2) The library has an error code global variable, much like `errno' in
>the Standard C library.  This error code variable must somehow be
>converted into thread-specific data.

My first suggestion is "change the interface"; don't set a global variable
but rather return a meaningful error number.

Quote:>The nicest solution would be to use thread-local storage (TLS), with
>support from the linker, thread-library, compiler, and assembler.  The
>Solaris 9 12/02 "Linker and Libraries Guide" suggests that the linker
>supports TLS, but I cannot find anything about how to use this from
>within C source code.

TLS is only supported in S9 12/02 and later so if you want others
to use the code you may want to postpone it.

Quote:>Perhaps this feature is not quite ready for use yet?

I don't think there's compiler support yet.

[TLS appeared in the first Sun papers on Solaris threads and was
at that time also implemented in the compiler but *never* in the
linker; it was subsequently removed and redesigned once the performance
advantages became very clear]

Quote:>Otherwise, I suppose I must use the pthread_key_create,
>pthread_setspecific, and pthread_getspecific functions?  And the key
>must be created using a pthread_once_t control unless the user is
>required to create the key explicitly?

errno works more or less the same; but if at all possible return the
error from the function.

Casper
--
Expressed in this posting are my opinions.  They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.

 
 
 

Making a library thread-safe

Post by Eric We » Sat, 08 Feb 2003 06:36:47




> >1) Sun's "Multithreaded Programming Guide" states that modules of a
> >multi-threaded application should be compiled with either -D_REENTRANT
> >or -D_POSIX_C_SOURCE=199506L (or both).  To get a single-threaded
> >application, none of these flags should be defined.  Page 167 of the
> >May 2002 version of this guide says: "This applies to every module of
> >an application."

> >Does this imply that it is impossible to create a single thread-safe
> >version of the library that can be linked into both single-threaded
> >and multi-threaded applications?

> No, all system libraries are both thread safe and can be linked
> by single threaded apps.

I notice that _REEMTRANT causes errno to be defined as __errno(). This
is presumably a thread safe routine. How is the thread safety managed?
Are thread locks/mutexes employed? If so, how is it possible for a
single threaded appl to link to a _REENTRANT compiled library w/o
explicitly linking to one of the thread libraries? (Was -z allextract
used to compile the library?)

Quote:

> >[I would prefer to not have to create two or perhaps four versions of
> >the library for each possible combination of the above mentioned
> >flags.]

> Compile it with -D_REENTRANT (but do not link the library with -lpthread)
> Also, make sure the library is self-contained [i.e., link it with libc
> and all other libraries it needs]

> >2) The library has an error code global variable, much like `errno' in
> >the Standard C library.  This error code variable must somehow be
> >converted into thread-specific data.

> My first suggestion is "change the interface"; don't set a global variable
> but rather return a meaningful error number.

[snip]

Quote:

> >Otherwise, I suppose I must use the pthread_key_create,
> >pthread_setspecific, and pthread_getspecific functions?  And the key
> >must be created using a pthread_once_t control unless the user is
> >required to create the key explicitly?

> errno works more or less the same;

Can you elaborate? This gets back to my question about not needing to
link w/ a threads library when compiling w/ _REENTRANT.

Much thanks!

  --Eric

 
 
 

Making a library thread-safe

Post by Casper H.S. Di » Mon, 10 Feb 2003 00:42:08



>I notice that _REEMTRANT causes errno to be defined as __errno(). This
>is presumably a thread safe routine. How is the thread safety managed?
>Are thread locks/mutexes employed? If so, how is it possible for a
>single threaded appl to link to a _REENTRANT compiled library w/o
>explicitly linking to one of the thread libraries? (Was -z allextract
>used to compile the library?)

"errno" is defined as (*__errno()); the __errno() function returns a
pointer to a "thread specific" version of errno.  No locks are
necessary.

Yes, it is possible for an applications to link with a threaded library;
case in point: all Solaris system libraries (all MT) and all single threaded
SOlaris apps (not -D_REENTRANT).

For single threaded apps or the main thread, &errno == __errno();

Quote:>Can you elaborate? This gets back to my question about not needing to
>link w/ a threads library when compiling w/ _REENTRANT.

Typically for Solaris threads you could use something thr_main:

        if (thr_main() == 0) {
                /* Use thread specific data */
                ....
        } else {
                /* main thread or not threaded, use global data. */
                return (&errno);

        }

I don't think there's a portable way, though.

Casper
--
Expressed in this posting are my opinions.  They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.

 
 
 

1. Making libraries thread-safe

Hey all:

Does anyone have any information or pointers on what kind of
semaphores/mutexes should be used to make a library thread-safe (as well
as signal safe) in a situation where:

1) There's no way to know if an app is threaded at all--and if it _is_
what kind of threading it's using (Netscape seems to be an example of
this, at least the version linked to the glibc-2.0 series).

2) The Right way to do it (i.e. pthreads semaphores--sem_init(),
sem_wait(), sem_post() ) isn't really available as an option (there are
deep reasons for this that have to do with the nature of the library; I
can elaborate on request).

One situation that may _not_ have a solution would be running on top of
a non-pre-emptive thread system (a thread spinning on a lock in a
handler would just keep spinning); fortunately `gotcha' cases--if
they're well-understood--are OK.

Many thanks.
--ag

--
Artie Gold, Austin, TX  (finger the cs.utexas.edu account for more info)

--
A: Look for a lawyer who speaks Aramaic...about trademark infringement.

2. RICHPse and quad 10/100 nic (qfe)

3. Using thread-safe C library functions.

4. Perl or shell scripts

5. using thread-safe library code without -lpthreads

6. Linux with WaveLAN Cards

7. Thread-safe C libraries in Solaris?

8. sshd hangs on remore command

9. Solaris 8 threads: If a routine is Async-Signal-Safe is it also thread Safe?

10. mmap, thread-safe, and signal-safe

11. Thread-safe and Signal-safe

12. Making gcc thread safe.

13. How to make a thread safe library