summaryrefslogtreecommitdiffstats
path: root/man/man3/pthread_key_create.3
diff options
context:
space:
mode:
Diffstat (limited to 'man/man3/pthread_key_create.3')
-rw-r--r--man/man3/pthread_key_create.3178
1 files changed, 178 insertions, 0 deletions
diff --git a/man/man3/pthread_key_create.3 b/man/man3/pthread_key_create.3
new file mode 100644
index 000000000..ad8a397f4
--- /dev/null
+++ b/man/man3/pthread_key_create.3
@@ -0,0 +1,178 @@
+.\" Copyright, Xavier Leroy <Xavier.Leroy@inria.fr>
+.\" Copyright 2023, Alejandro Colomar <alx@kernel.org>
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.TH pthread_key_create 3 (date) "Linux man-pages (unreleased)"
+.
+.
+.SH NAME
+pthread_key_create,
+pthread_key_delete,
+pthread_setspecific,
+pthread_getspecific
+\-
+management of thread-specific data
+.
+.
+.SH SYNOPSIS
+.B #include <pthread.h>
+.P
+.BI "int pthread_key_create(pthread_key_t *" key ", void (*" destr_function ") (void *));"
+.BI "int pthread_key_delete(pthread_key_t " key ");"
+.BI "int pthread_setspecific(pthread_key_t " key ", const void *" pointer ");"
+.BI "void * pthread_getspecific(pthread_key_t " key ");"
+.
+.
+.SH DESCRIPTION
+Programs often need global or static variables
+that have different values in different threads.
+Since threads share one memory space,
+this cannot be achieved with regular variables.
+Thread-specific data is the POSIX threads answer to this need.
+.P
+Each thread possesses a private memory block,
+the thread-specific data area,
+or TSD area for short.
+This area is indexed by TSD keys.
+The TSD area associates values of type \fBvoid *\fP to TSD keys.
+TSD keys are common to all threads,
+but the value associated with a given TSD key
+can be different in each thread.
+.P
+For concreteness,
+the TSD areas can be viewed as arrays of \fBvoid *\fP pointers,
+TSD keys as integer indices into these arrays,
+and the value of a TSD key
+as the value of the corresponding array element in the calling thread.
+.P
+When a thread is created,
+its TSD area initially associates \fBNULL\fP with all keys.
+.P
+\fBpthread_key_create\fP allocates a new TSD key.
+The key is stored in the location pointed to by \fIkey\fP.
+There is a limit of \fBPTHREAD_KEYS_MAX\fP
+on the number of keys allocated at a given time.
+The value initially associated with the returned key
+is \fBNULL\fP in all currently executing threads.
+.P
+The \fIdestr_function\fP argument,
+if not \fBNULL\fP,
+specifies a destructor function associated with the key.
+When a thread terminates via \fBpthread_exit\fP or by cancelation,
+\fIdestr_function\fP is called with arguments
+the value associated with the key in that thread.
+The \fIdestr_function\fP is not called if that value is \fBNULL\fP.
+The order in which destructor functions are called at thread termination time
+is unspecified.
+.P
+Before the destructor function is called,
+the \fBNULL\fP value is associated with the key in the current thread.
+A destructor function might,
+however,
+re-associate non-\fBNULL\fP values to that key or some other key.
+To deal with this,
+if after all the destructors have been called
+for all non-\fBNULL\fP values,
+there are still some non-\fBNULL\fP values with associated destructors,
+then the process is repeated.
+The glibc implementation stops the process
+after \fBPTHREAD_DESTRUCTOR_ITERATIONS\fP iterations,
+even if some non-\fBNULL\fP values with associated descriptors remain.
+Other implementations may loop indefinitely.
+.P
+\fBpthread_key_delete\fP deallocates a TSD key.
+It does not check
+whether non-\fBNULL\fP values are associated with that key
+in the currently executing threads,
+nor call the destructor function associated with the key.
+.P
+\fBpthread_setspecific\fP changes the value
+associated with \fIkey\fP in the calling thread,
+storing the given \fIpointer\fP instead.
+.P
+\fBpthread_getspecific\fP returns the value
+currently associated with \fIkey\fP in the calling thread.
+.
+.
+.SH "RETURN VALUE"
+\fBpthread_key_create\fP,
+\fBpthread_key_delete\fP,
+and \fBpthread_setspecific\fP
+return 0 on success and a non-zero error code on failure.
+If successful,
+\fBpthread_key_create\fP stores the newly allocated key
+in the location pointed to by its \fIkey\fP argument.
+.P
+\fBpthread_getspecific\fP returns
+the value associated with \fIkey\fP on success,
+and \fBNULL\fP on error.
+.
+.
+.SH ERRORS
+\fBpthread_key_create\fP returns the following error code on error:
+.RS
+.TP
+\fBEAGAIN\fP
+\fBPTHREAD_KEYS_MAX\fP keys are already allocated.
+.RE
+.P
+\fBpthread_key_delete\fP and \fBpthread_setspecific\fP return
+the following error code on error:
+.RS
+.TP
+\fBEINVAL\fP
+\fIkey\fP is not a valid, allocated TSD key.
+.RE
+.P
+\fBpthread_getspecific\fP returns \fBNULL\fP if \fIkey\fP is not a valid,
+allocated TSD key.
+.
+.
+.SH "SEE ALSO"
+pthread_create(3), pthread_exit(3), pthread_testcancel(3).
+.
+.
+.SH EXAMPLE
+The following code fragment
+allocates a thread-specific array of 100 characters,
+with automatic reclamation at thread exit:
+.P
+.RS
+.ft 3
+.nf
+.sp
+/* Key for the thread-specific buffer */
+static pthread_key_t buffer_key;
+\&
+/* Once-only initialisation of the key */
+static pthread_once_t buffer_key_once = PTHREAD_ONCE_INIT;
+\&
+/* Allocate the thread-specific buffer */
+void buffer_alloc(void)
+{
+ pthread_once(&buffer_key_once, buffer_key_alloc);
+ pthread_setspecific(buffer_key, malloc(100));
+}
+\&
+/* Return the thread-specific buffer */
+char * get_buffer(void)
+{
+ return (char *) pthread_getspecific(buffer_key);
+}
+\&
+/* Allocate the key */
+static void buffer_key_alloc()
+{
+ pthread_key_create(&buffer_key, buffer_destroy);
+}
+\&
+/* Free the thread-specific buffer */
+static void buffer_destroy(void * buf)
+{
+ free(buf);
+}
+.ft
+.P
+.RE
+.fi