Chris Stith wrote:

> The documentation for a library should state whether or not it is
> thread-safe. Serializing calls to a library certainly doesn't make
> it thread-safe, but serializing calls to individual nonreentrant
> functions within the library keeps them from puking all over your
> program.
> 
> My suggestion is to let libraries that are threadsafe (system
> libraries as well as Perl moduels would be nice) be used as such
> so the advantages of that can be realized, while at the same time
> defaulting to serialized calls for libraries which are not, so
> your threaded programs which need to call nonreentrant functions
> can do so with some level of safety.

Thread safety actually comes in a series of flavours - see the manpage
excerpt below.  Also, assuming that the same level of MT-safeness applies to
the whole of a library is incorrect - take for example libc, which contains
everything from Unsafe to Async-signal-safe functions.

Alan Burlison



Standards, Environments, and Macros                 attributes(5)

  MT-Level

     Libraries are classified into four categories  which  define
     their ability to support multiple threads. Manual pages con-
     taining routines that are of multiple or   differing  levels
     show this within their NOTES or USAGE section.

     Safe  Safe is an attribute of code that can be called from a
           multithreaded  application. The effect of calling into
           a Safe interface or a safe code segment  is  that  the
           results   are  valid  even  when  called  by  multiple
           threads.  Often overlooked is the fact that the result
           of  this  Safe interface or safe code segment can have
           global consequences  that  affect  all  threads.   For
           example,  the action of opening or closing a file from
           one thread is visible by all the threads within a pro-
           cess.   A multi-threaded application has the responsi-
           bility for using these interfaces in  a  safe  manner,
           which  is  different from whether or not the interface
           is Safe.  For example,  a  multi-threaded  application
           that  closes  a  file  that  is  still in use by other
           threads  within  the  application  is  not  using  the
           close(2) interface safely.

     Unsafe
           An Unsafe library contains global and static data that
           is  not  protected.   It is not safe to use unless the
           application arranges for only one thread  at  time  to
           execute within the library. Unsafe libraries may  con-
           tain routines that are  Safe;  however,  most  of  the
           library's routines are unsafe to call.

           The following table  contains  reentrant  counterparts
           for Unsafe functions.  This table is subject to change
           by Sun.

           Reentrant functions for libc:

           Unsafe Function               Reentrant counterpart
           ctime                         ctime_r
           localtime                     localtime_r
           asctime                       asctime_r
           gmtime                        gmtime_r
           ctermid                       ctermid_r
           getlogin                      getlogin_r
           rand                          rand_r
           readdir                       readdir_r
           strtok                        strtok_r
           tmpnam                        tmpnam_r

     MT-Safe
           An MT-Safe library is fully prepared for multithreaded
           access.  It  protects  its global and static data with
           locks, and can provide a  reasonable  amount  of  con-
           currency.  Note that a library can be safe to use, but
           not  MT-Safe.  For  example,  surrounding  an   entire
           library  with a monitor makes the library Safe, but it
           supports no concurrency so it is  not  considered  MT-
           Safe.  An  MT-Safe  library  must  permit a reasonable
           amount of concurrency. (This definition's  purpose  is
           to  give  precision to what is meant when a library is
           described as Safe.  The definition of a  Safe  library
           does  not specify if the library supports concurrency.
           The MT-Safe definition makes it clear that the library
           is  Safe,  and supports some concurrency.  This clari-
           fies the Safe definition, which can mean anything from
           being  single  threaded  to  being  any degree of mul-
           tithreaded.)

     Async-Signal-Safe
           Async-Signal-Safe refers to  particular  library  rou-
           tines that can be safely called from a signal handler.
           A thread that is executing an  Async-Signal-Safe  rou-
           tine will not deadlock with itself if interrupted by a
           signal. Signals are only a problem  for  MT-Safe  rou-
           tines that acquire locks.

           Signals  are  disabled  when  locks  are  acquired  in
           Async-Signal-Safe  routines.  This  prevents  a signal
           handler that might acquire the same  lock  from  being
           called.   The   list  of  Async-Signal-Safe  functions
           includes:

           _exit                access                aio_error
           aio_return           aio_suspend           alarm
           cfgetispeed          cfgetospeed           cfsetispeed
           cfsetospeed          chdir                 chmod
           chown                clock_gettime         close
           creat                dup                   dup2
           execle               execve                fcntl
           fdatasync            fork                  fstat
           fsync                getegid               geteuid
           getgid               getgroups             getpgrp
           getpid               getppid               getuid
           kill                 link                  lseek
           mkdir                mkfifo                open
           pathconf             pause                 pipe
           read                 rename                rmdir
           sem_post             sema_post             setgid
           setpgid              setsid                setuid
           sigaction            sigaddset             sigdelset
           sigemptyset          sigfillset            sigismember
           sigpending           sigprocmask           sigqueue
           sigsuspend           sleep                 stat
           sysconf              tcdrain               tcflow
           tcflush              tcgetattr             tcgetpgrp
           tcsendbreak          tcsetattr             tcsetpgrp
           thr_kill             thr_sigsetmask        time
           timer_getoverrun     timer_gettime         timer_settime
           times                umask                 uname
           unlink               utime                 wait
           waitpid              write

     MT-Safe with Exceptions
           See the NOTES or USAGE sections of these pages  for  a
           description of the exceptions.

     Safe with Exceptions
           See the NOTES or USAGE sections of these pages  for  a
           description of the exceptions.

     Fork1-Safe
           A Fork1-Safe library releases the locks  it  had  held
           whenever  fork1(2)  is called in a Solaris thread pro-
           gram, or fork(2) in a POSIX (see standards(5))  thread
           program.   Calling  fork(2)  in a POSIX thread program
           has the same semantic as calling fork1(2) in a Solaris
           thread program. All system calls, libpthread, and lib-
           thread are Fork1-Safe. Otherwise,  you  should  handle
           the      locking      clean-up      yourself      (see
           pthread_atfork(3THR)).

     Cancel-Safety
           If     a     multi-threaded      application      uses
           pthread_cancel(3THR)  to  cancel  (that  is,  kill)  a
           thread, it is  possible  that  the  target  thread  is
           killed  while  holding  a  resource, such as a lock or
           allocated memory. If the thread has not installed  the
           appropriate  cancellation  cleanup handlers to release
           the        resources        appropriately         (see
           pthread_cancel(3THR)),  the  application  is  "cancel-
           unsafe", that is, it is not safe with respect to  can-
           cellation. This unsafety could result in deadlocks due
           to locks not released by a thread that gets cancelled,
           or resource leaks; for example, memory not being freed
           on thread  cancellation.  All  applications  that  use
           pthread_cancel(3THR)  should  ensure that they operate
           in a Cancel-Safe environment. Libraries that have can-
           cellation  points  and which acquire resources such as
           locks or allocate memory dynamically, also  contribute
           to the cancel-unsafety of applications that are linked
           with these libraries. This introduces another level of
           safety  for  libraries  in  a  multi-threaded program:
           Cancel-Safety.  There  are   two   sub-categories   of
           Cancel-Safety:       Deferred-Cancel-Safety,       and
           Asynchronous-Cancel-Safety.  An  application  is  con-
           sidered  to be Deferred-Cancel-Safe when it is Cancel-
           Safe  for   threads   whose   cancellation   type   is
           PTHREAD_CANCEL_DEFERRED.  An application is considered
           to be Asynchronous-Cancel-Safe when it is  Cancel-Safe
           for     threads    whose    cancellation    type    is
           PTHREAD_CANCEL_ASYNCHRONOUS. Deferred-Cancel-Safety is
           easier  to  achieve  than  Asynchronous-Cancel-Safety,
           since a thread with the deferred cancellation type can
           be cancelled only at well-defined cancellation points,
           whereas a thread with  the  asynchronous  cancellation
           type  can be cancelled anywhere. Since all threads are
           created by default to have the  deferred  cancellation
           type,  it  may never be necessary to worry about asyn-
           chronous cancel safety. Indeed, most applications  and
           libraries  are  expected  to  always  be Asynchronous-
           Cancel-Unsafe.  An application which is  Asynchronous-
           Cancel-Safe  is  also, by definition, Deferred-Cancel-
           Safe.

Reply via email to