Provided by: manpages-posix-dev_2013a-2_all bug

PROLOG

       This  manual  page  is part of the POSIX Programmer's Manual.  The Linux implementation of this interface
       may differ (consult the corresponding Linux manual page for details of Linux behavior), or the  interface
       may not be implemented on Linux.

NAME

       pthread_atfork — register fork handlers

SYNOPSIS

       #include <pthread.h>

       int pthread_atfork(void (*prepare)(void), void (*parent)(void),
           void (*child)(void));

DESCRIPTION

       The  pthread_atfork()  function  shall declare fork handlers to be called before and after fork(), in the
       context of the thread that called fork().  The  prepare  fork  handler  shall  be  called  before  fork()
       processing  commences.  The  parent  fork handle shall be called after fork() processing completes in the
       parent process. The child fork handler shall be called after fork() processing  completes  in  the  child
       process.  If  no handling is desired at one or more of these three points, the corresponding fork handler
       address(es) may be set to NULL.

       The order of calls to pthread_atfork() is significant. The parent and child fork handlers shall be called
       in  the  order  in  which  they were established by calls to pthread_atfork().  The prepare fork handlers
       shall be called in the opposite order.

RETURN VALUE

       Upon successful completion, pthread_atfork() shall return a value of zero;  otherwise,  an  error  number
       shall be returned to indicate the error.

ERRORS

       The pthread_atfork() function shall fail if:

       ENOMEM Insufficient table space exists to record the fork handler addresses.

       The pthread_atfork() function shall not return an error code of [EINTR].

       The following sections are informative.

EXAMPLES

       None.

APPLICATION USAGE

       None.

RATIONALE

       There  are  at  least  two serious problems with the semantics of fork() in a multi-threaded program. One
       problem has to do with state (for example, memory) covered by mutexes. Consider the case where one thread
       has a mutex locked and the state covered by that mutex is inconsistent while another thread calls fork().
       In the child, the mutex is in the locked state (locked by a nonexistent thread  and  thus  can  never  be
       unlocked).  Having the child simply reinitialize the mutex is unsatisfactory since this approach does not
       resolve the question about how to correct or otherwise deal with the inconsistent state in the child.

       It is suggested that programs that use fork() call an exec function very soon  afterwards  in  the  child
       process,  thus  resetting  all  states.  In  the meantime, only a short list of async-signal-safe library
       routines are promised to be available.

       Unfortunately, this solution does not address the needs of multi-threaded libraries. Application programs
       may  not  be  aware  that  a  multi-threaded  library is in use, and they feel free to call any number of
       library routines between the fork() and exec calls, just as they always have. Indeed, they may be  extant
       single-threaded  programs  and  cannot,  therefore,  be  expected to obey new restrictions imposed by the
       threads library.

       On the other hand, the multi-threaded library needs a way to protect its internal state during fork()  in
       case  it  is  re-entered  later in the child process. The problem arises especially in multi-threaded I/O
       libraries, which are almost sure to  be  invoked  between  the  fork()  and  exec  calls  to  effect  I/O
       redirection.  The  solution  may  require  locking mutex variables during fork(), or it may entail simply
       resetting the state in the child after the fork() processing completes.

       The pthread_atfork() function was intended to provide multi-threaded libraries with a  means  to  protect
       themselves from innocent application programs that call fork(), and to provide multi-threaded application
       programs with a standard mechanism for protecting themselves from fork() calls in a  library  routine  or
       the application itself.

       The  expected  usage  was  that  the prepare handler would acquire all mutex locks and the other two fork
       handlers would release them.

       For example, an application could have supplied a prepare routine that acquires the necessary mutexes the
       library  maintains  and supplied child and parent routines that release those mutexes, thus ensuring that
       the child would have got a consistent snapshot of the state of the library (and  that  no  mutexes  would
       have  been left stranded). This is good in theory, but in reality not practical. Each and every mutex and
       lock in the process must be located and locked.  Every  component  of  a  program  including  third-party
       components  must  participate  and  they  must  agree who is responsible for which mutex or lock. This is
       especially problematic for mutexes and locks in dynamically  allocated  memory.  All  mutexes  and  locks
       internal  to the implementation must be locked, too. This possibly delays the thread calling fork() for a
       long time or even indefinitely since uses of these synchronization objects may not be  under  control  of
       the  application. A final problem to mention here is the problem of locking streams. At least the streams
       under control of the system (like stdin, stdout, stderr) must be protected by  locking  the  stream  with
       flockfile().   But  the  application  itself  could  have  done that, possibly in the same thread calling
       fork().  In this case, the process will deadlock.

       Alternatively, some libraries might have been able to supply just a child routine that reinitializes  the
       mutexes  in  the library and all associated states to some known value (for example, what it was when the
       image was originally executed). This approach  is  not  possible,  though,  because  implementations  are
       allowed  to  fail  *_init()  and  *_destroy()  calls  for mutexes and locks if the mutex or lock is still
       locked. In this case, the child routine is not able to reinitialize the mutexes and locks.

       When fork() is called, only the calling thread is  duplicated  in  the  child  process.   Synchronization
       variables remain in the same state in the child as they were in the parent at the time fork() was called.
       Thus, for example, mutex locks may be held by threads that no longer exist in the child process, and  any
       associated  states may be inconsistent. The intention was that the parent process could have avoided this
       by explicit code that acquires and releases  locks  critical  to  the  child  via  pthread_atfork().   In
       addition, any critical threads would have needed to be recreated and reinitialized to the proper state in
       the child (also via pthread_atfork()).

       A higher-level package may acquire locks on its own data structures before invoking lower-level packages.
       Under  this  scenario,  the order specified for fork handler calls allows a simple rule of initialization
       for avoiding package deadlock: a package initializes all packages on which it depends before it calls the
       pthread_atfork() function for itself.

       As  explained, there is no suitable solution for functionality which requires non-atomic operations to be
       protected through mutexes and locks. This is why the POSIX.1 standard since  the  1996  release  requires
       that the child process after fork() in a multi-threaded process only calls async-signal-safe interfaces.

FUTURE DIRECTIONS

       None.

SEE ALSO

       atexit(), exec, fork()

       The Base Definitions volume of POSIX.1‐2008, <pthread.h>, <sys_types.h>

COPYRIGHT

       Portions of this text are reprinted and reproduced in electronic form from IEEE Std 1003.1, 2013 Edition,
       Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open  Group  Base
       Specifications  Issue 7, Copyright (C) 2013 by the Institute of Electrical and Electronics Engineers, Inc
       and The Open Group.  (This is POSIX.1-2008 with the 2013 Technical Corrigendum 1 applied.) In  the  event
       of  any  discrepancy between this version and the original IEEE and The Open Group Standard, the original
       IEEE and The Open Group Standard is the referee document. The original Standard can be obtained online at
       http://www.unix.org/online.html .

       Any  typographical  or formatting errors that appear in this page are most likely to have been introduced
       during  the  conversion  of  the  source  files  to  man  page  format.  To  report  such   errors,   see
       https://www.kernel.org/doc/man-pages/reporting_bugs.html .