diff options
Diffstat (limited to 'upstream/archlinux/man3p/pthread_atfork.3p')
-rw-r--r-- | upstream/archlinux/man3p/pthread_atfork.3p | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/upstream/archlinux/man3p/pthread_atfork.3p b/upstream/archlinux/man3p/pthread_atfork.3p new file mode 100644 index 00000000..8f3f5a7f --- /dev/null +++ b/upstream/archlinux/man3p/pthread_atfork.3p @@ -0,0 +1,262 @@ +'\" et +.TH PTHREAD_ATFORK "3P" 2017 "IEEE/The Open Group" "POSIX Programmer's Manual" +.\" +.SH 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. +.\" +.SH NAME +pthread_atfork +\(em register fork handlers +.SH SYNOPSIS +.LP +.nf +#include <pthread.h> +.P +int pthread_atfork(void (*\fIprepare\fP)(void), void (*\fIparent\fP)(void), + void (*\fIchild\fP)(void)); +.fi +.SH DESCRIPTION +The +\fIpthread_atfork\fR() +function shall declare fork handlers to be called before and after +\fIfork\fR(), +in the context of the thread that called +\fIfork\fR(). +The +.IR prepare +fork handler shall be called before +\fIfork\fR() +processing commences. The +.IR parent +fork handle shall be called after +\fIfork\fR() +processing completes in the parent process. The +.IR child +fork handler shall be called after +\fIfork\fR() +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. +.P +If a +\fIfork\fR() +call in a multi-threaded process leads to a +.IR child +fork handler calling any function that is not async-signal-safe, the +behavior is undefined. +.P +The order of calls to +\fIpthread_atfork\fR() +is significant. The +.IR parent +and +.IR child +fork handlers shall be called in the order in which they were +established by calls to +\fIpthread_atfork\fR(). +The +.IR prepare +fork handlers shall be called in the opposite order. +.SH "RETURN VALUE" +Upon successful completion, +\fIpthread_atfork\fR() +shall return a value of zero; otherwise, an error number shall be +returned to indicate the error. +.SH ERRORS +The +\fIpthread_atfork\fR() +function shall fail if: +.TP +.BR ENOMEM +Insufficient table space exists to record the fork handler addresses. +.P +The +\fIpthread_atfork\fR() +function shall not return an error code of +.BR [EINTR] . +.LP +.IR "The following sections are informative." +.SH EXAMPLES +None. +.SH "APPLICATION USAGE" +The original usage pattern envisaged for +\fIpthread_atfork\fR() +was for the +.IR prepare +fork handler to lock mutexes and other locks, and for the +.IR parent +and +.IR child +handlers to unlock them. However, since all of the relevant unlocking +functions, except +\fIsem_post\fR(), +are not async-signal-safe, this usage results in undefined behavior in +the child process unless the only such unlocking function it calls is +\fIsem_post\fR(). +.SH RATIONALE +There are at least two serious problems with the semantics of +\fIfork\fR() +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 +\fIfork\fR(). +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. +.P +It is suggested that programs that use +\fIfork\fR() +call an +.IR 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. +.P +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 +\fIfork\fR() +and +.IR 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. +.P +On the other hand, the multi-threaded library needs a way to protect +its internal state during +\fIfork\fR() +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 +\fIfork\fR() +and +.IR exec +calls to effect I/O redirection. The solution may require locking +mutex variables during +\fIfork\fR(), +or it may entail simply resetting the state in the child after the +\fIfork\fR() +processing completes. +.P +The +\fIpthread_atfork\fR() +function was intended to provide multi-threaded libraries with a means +to protect themselves from innocent application programs that call +\fIfork\fR(), +and to provide multi-threaded application programs with a standard +mechanism for protecting themselves from +\fIfork\fR() +calls in a library routine or the application itself. +.P +The expected usage was that the prepare handler would acquire all mutex +locks and the other two fork handlers would release them. +.P +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 +\fIfork\fR() +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 +.IR stdin , +.IR stdout , +.IR stderr ) +must be protected by locking the stream with +\fIflockfile\fR(). +But the application itself could have done that, possibly in the same +thread calling +\fIfork\fR(). +In this case, the process will deadlock. +.P +Alternatively, some libraries might have been able to supply just a +.IR 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 +.IR *_init (\|) +and +.IR *_destroy (\|) +calls for mutexes and locks if the mutex or lock is still locked. In +this case, the +.IR child +routine is not able to reinitialize the mutexes and locks. +.P +When +\fIfork\fR() +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 +\fIfork\fR() +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 +\fIpthread_atfork\fR(). +In addition, any critical threads would have needed to be recreated and +reinitialized to the proper state in the child (also via +\fIpthread_atfork\fR()). +.P +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 +\fIpthread_atfork\fR() +function for itself. +.P +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 +\fIfork\fR() +in a multi-threaded process only calls async-signal-safe interfaces. +.SH "FUTURE DIRECTIONS" +The +\fIpthread_atfork\fR() +function may be formally deprecated (for example, by shading it OB) in +a future version of this standard. +.SH "SEE ALSO" +.IR "\fIatexit\fR\^(\|)", +.IR "\fIexec\fR\^", +.IR "\fIfork\fR\^(\|)" +.P +The Base Definitions volume of POSIX.1\(hy2017, +.IR "\fB<pthread.h>\fP", +.IR "\fB<sys_types.h>\fP" +.\" +.SH COPYRIGHT +Portions of this text are reprinted and reproduced in electronic form +from IEEE Std 1003.1-2017, Standard for Information Technology +-- Portable Operating System Interface (POSIX), The Open Group Base +Specifications Issue 7, 2018 Edition, +Copyright (C) 2018 by the Institute of +Electrical and Electronics Engineers, Inc and The Open Group. +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.opengroup.org/unix/online.html . +.PP +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 . |