diff options
Diffstat (limited to 'man3p/pthread_key_create.3p')
-rw-r--r-- | man3p/pthread_key_create.3p | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/man3p/pthread_key_create.3p b/man3p/pthread_key_create.3p new file mode 100644 index 000000000..3da43c967 --- /dev/null +++ b/man3p/pthread_key_create.3p @@ -0,0 +1,233 @@ +.\" Copyright (c) 2001-2003 The Open Group, All Rights Reserved +.TH "PTHREAD_KEY_CREATE" P 2003 "IEEE/The Open Group" "POSIX Programmer's Manual" +.\" pthread_key_create +.SH NAME +pthread_key_create \- thread-specific data key creation +.SH SYNOPSIS +.LP +\fB#include <pthread.h> +.br +.sp +int pthread_key_create(pthread_key_t *\fP\fIkey\fP\fB, void (*\fP\fIdestructor\fP\fB)(void*)); +\fP +\fB +.br +\fP +.SH DESCRIPTION +.LP +The \fIpthread_key_create\fP() function shall create a thread-specific +data key visible to all threads in the process. Key +values provided by \fIpthread_key_create\fP() are opaque objects used +to locate thread-specific data. Although the same key value +may be used by different threads, the values bound to the key by \fIpthread_setspecific\fP() +are maintained on a per-thread basis and persist for the +life of the calling thread. +.LP +Upon key creation, the value NULL shall be associated with the new +key in all active threads. Upon thread creation, the value +NULL shall be associated with all defined keys in the new thread. +.LP +An optional destructor function may be associated with each key value. +At thread exit, if a key value has a non-NULL destructor +pointer, and the thread has a non-NULL value associated with that +key, the value of the key is set to NULL, and then the function +pointed to is called with the previously associated value as its sole +argument. The order of destructor calls is unspecified if +more than one destructor exists for a thread when it exits. +.LP +If, after all the destructors have been called for all non-NULL values +with associated destructors, there are still some +non-NULL values with associated destructors, then the process is repeated. +If, after at least {PTHREAD_DESTRUCTOR_ITERATIONS} +iterations of destructor calls for outstanding non-NULL values, there +are still some non-NULL values with associated destructors, +implementations may stop calling destructors, or they may continue +calling destructors until no non-NULL values with associated +destructors exist, even though this might result in an infinite loop. +.SH RETURN VALUE +.LP +If successful, the \fIpthread_key_create\fP() function shall store +the newly created key value at *\fIkey\fP and shall return +zero. Otherwise, an error number shall be returned to indicate the +error. +.SH ERRORS +.LP +The \fIpthread_key_create\fP() function shall fail if: +.TP 7 +.B EAGAIN +The system lacked the necessary resources to create another thread-specific +data key, or the system-imposed limit on the total +number of keys per process {PTHREAD_KEYS_MAX} has been exceeded. +.TP 7 +.B ENOMEM +Insufficient memory exists to create the key. +.sp +.LP +The \fIpthread_key_create\fP() function shall not return an error +code of [EINTR]. +.LP +\fIThe following sections are informative.\fP +.SH EXAMPLES +.LP +The following example demonstrates a function that initializes a thread-specific +data key when it is first called, and +associates a thread-specific object with each calling thread, initializing +this object when necessary. +.sp +.RS +.nf + +\fBstatic pthread_key_t key; +static pthread_once_t key_once = PTHREAD_ONCE_INIT; +.sp + +static void +make_key() +{ + (void) pthread_key_create(&key, NULL); +} +.sp + +func() +{ + void *ptr; +.sp + + (void) pthread_once(&key_once, make_key); + if ((ptr = pthread_getspecific(key)) == NULL) { + ptr = malloc(OBJECT_SIZE); + ... + (void) pthread_setspecific(key, ptr); + } + ... +} +\fP +.fi +.RE +.LP +Note that the key has to be initialized before \fIpthread_getspecific\fP() +or \fIpthread_setspecific\fP() can be used. The \fIpthread_key_create\fP() +call could either be explicitly made in a module initialization routine, +or it can be done implicitly by the first call to a module +as in this example. Any attempt to use the key before it is initialized +is a programming error, making the code below +incorrect. +.sp +.RS +.nf + +\fBstatic pthread_key_t key; +.sp + +func() +{ + void *ptr; +.sp + + /* KEY NOT INITIALIZED!!! THIS WON'T WORK!!! */ + if ((ptr = pthread_getspecific(key)) == NULL && + pthread_setspecific(key, NULL) != 0) { + pthread_key_create(&key, NULL); + ... + } +} +\fP +.fi +.RE +.SH APPLICATION USAGE +.LP +None. +.br +.SH RATIONALE +.LP +.SS Destructor Functions +.LP +Normally, the value bound to a key on behalf of a particular thread +is a pointer to storage allocated dynamically on behalf of +the calling thread. The destructor functions specified with \fIpthread_key_create\fP() +are intended to be used to free this +storage when the thread exits. Thread cancellation cleanup handlers +cannot be used for this purpose because thread-specific data +may persist outside the lexical scope in which the cancellation cleanup +handlers operate. +.LP +If the value associated with a key needs to be updated during the +lifetime of the thread, it may be necessary to release the +storage associated with the old value before the new value is bound. +Although the \fIpthread_setspecific\fP() function could do this automatically, +this feature is not +needed often enough to justify the added complexity. Instead, the +programmer is responsible for freeing the stale storage: +.sp +.RS +.nf + +\fBpthread_getspecific(key, &old); +new = allocate(); +destructor(old); +pthread_setspecific(key, new); +\fP +.fi +.RE +.TP 7 +\fBNote:\fP +The above example could leak storage if run with asynchronous cancellation +enabled. No such problems occur in the default +cancellation state if no cancellation points occur between the get +and set. +.sp +.LP +There is no notion of a destructor-safe function. If an application +does not call \fIpthread_exit\fP() from a signal handler, or if it +blocks any signal whose handler may call +\fIpthread_exit\fP() while calling async-unsafe functions, all functions +may be +safely called from destructors. +.SS Non-Idempotent Data Key Creation +.LP +There were requests to make \fIpthread_key_create\fP() idempotent +with respect to a given \fIkey\fP address parameter. This +would allow applications to call \fIpthread_key_create\fP() multiple +times for a given \fIkey\fP address and be guaranteed that +only one key would be created. Doing so would require the key value +to be previously initialized (possibly at compile time) to a +known null value and would require that implicit mutual-exclusion +be performed based on the address and contents of the \fIkey\fP +parameter in order to guarantee that exactly one key would be created. +.LP +Unfortunately, the implicit mutual-exclusion would not be limited +to only \fIpthread_key_create\fP(). On many implementations, +implicit mutual-exclusion would also have to be performed by \fIpthread_getspecific\fP() +and \fIpthread_setspecific\fP() in order to guard against using incompletely +stored or +not-yet-visible key values. This could significantly increase the +cost of important operations, particularly \fIpthread_getspecific\fP(). +.LP +Thus, this proposal was rejected. The \fIpthread_key_create\fP() function +performs no implicit synchronization. It is the +responsibility of the programmer to ensure that it is called exactly +once per key before use of the key. Several straightforward +mechanisms can already be used to accomplish this, including calling +explicit module initialization functions, using mutexes, and +using \fIpthread_once\fP(). This places no significant burden on the +programmer, +introduces no possibly confusing \fIad hoc\fP implicit synchronization +mechanism, and potentially allows commonly used +thread-specific data operations to be more efficient. +.SH FUTURE DIRECTIONS +.LP +None. +.SH SEE ALSO +.LP +\fIpthread_getspecific\fP() , \fIpthread_key_delete\fP() , the Base +Definitions volume of IEEE\ Std\ 1003.1-2001, \fI<pthread.h>\fP +.SH COPYRIGHT +Portions of this text are reprinted and reproduced in electronic form +from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology +-- Portable Operating System Interface (POSIX), The Open Group Base +Specifications Issue 6, Copyright (C) 2001-2003 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 . |