import less(1)
[unleashed/tickless.git] / share / man / man3c / thr_keycreate.3c
blobf779d52dab2521ba7c11523461ac16af0f4f2745
1 '\" te
2 .\" Copyright (c) 2007, Sun Microsystems, Inc.  All Rights Reserved.
3 .\" Portions Copyright (c) 2001, the Institute of Electrical and Electronics Engineers, Inc. and The Open Group. All Rights Reserved.
4 .\" Portions Copyright (c) 1995 IEEE.  All Rights Reserved.
5 .\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
6 .\" http://www.opengroup.org/bookstore/.
7 .\" The Institute of Electrical and Electronics Engineers and The Open Group, have given us permission to reprint portions of their documentation. In the following statement, the phrase "this text" refers to portions of the system documentation. Portions of this text are reprinted and reproduced in electronic form in the Sun OS Reference Manual, from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any discrepancy between these versions 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.
8 .\"  This notice shall appear on any product containing this material.
9 .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License").  You may not use this file except in compliance with the License.
10 .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.  See the License for the specific language governing permissions and limitations under the License.
11 .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE.  If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
12 .TH THR_KEYCREATE 3C "Nov 2, 2007"
13 .SH NAME
14 thr_keycreate, thr_keycreate_once, thr_setspecific, thr_getspecific \-
15 thread-specific data functions
16 .SH SYNOPSIS
17 .LP
18 .nf
19 cc -mt [ \fIflag\fR... ] \fIfile\fR... [ \fIlibrary\fR... ]
20 #include <thread.h>
22 \fBint\fR \fBthr_keycreate\fR(\fBthread_key_t *\fR\fIkeyp\fR,
23      \fBvoid (*\fR\fIdestructor\fR)(void *));
24 .fi
26 .LP
27 .nf
28 \fBint\fR \fBthr_keycreate_once\fR(\fBthread_key_t *\fR\fIkeyp\fR,
29      \fBvoid (*\fR\fIdestructor\fR)(void *));
30 .fi
32 .LP
33 .nf
34 \fBint\fR \fBthr_setspecific\fR(\fBthread_key_t\fR \fIkey\fR, \fBvoid *\fR\fIvalue\fR);
35 .fi
37 .LP
38 .nf
39 \fBint\fR \fBthr_getspecific\fR(\fBthread_key_t\fR \fIkey\fR, \fBvoid **\fR\fIvaluep\fR);
40 .fi
42 .SH DESCRIPTION
43 .SS "Create Key"
44 .sp
45 .LP
46 In general, thread key creation allocates a key that locates data  specific to
47 each thread in the process. The key is global to all threads in the process,
48 which allows each thread to bind a value to the key once the key has been
49 created. The key independently maintains specific values for each binding
50 thread. The  \fBthr_keycreate()\fR function allocates a global \fIkey\fR
51 namespace, pointed to by \fIkeyp\fR, that is visible to all threads in the
52 process. Each thread is initially bound to a private element of this \fIkey\fR,
53 which allows access to its thread-specific data.
54 .sp
55 .LP
56 Upon key creation, a new key is assigned the value  \fINULL\fR for all active
57 threads. Additionally, upon thread creation, all previously created keys in the
58 new thread are assigned the value  \fINULL.\fR
59 .sp
60 .LP
61 Optionally, a destructor function  \fIdestructor\fR can be associated with each
62 \fIkey\fR. Upon thread exit, if a \fIkey\fR has a non-null \fIdestructor\fR
63 function and the thread has a non-null \fIvalue\fR associated with that
64 \fIkey\fR, the \fIdestructor\fR function is called with the current associated
65 \fIvalue\fR. If more than one \fIdestructor\fR exists for a thread when it
66 exits, the order of destructor calls is unspecified.
67 .sp
68 .LP
69 An exiting thread runs with all signals blocked. All thread termination
70 functions, including thread-specific data destructor functions, are called with
71 all signals blocked.
72 .sp
73 .LP
74 The \fBthr_keycreate_once()\fR function is identical to the
75 \fBthr_keycreate()\fR function except that the key pointed to by \fIkeyp\fR
76 must be statically initialized with the value \fBTHR_ONCE_KEY\fR before calling
77 \fBthr_keycreate_once()\fR and the key will be created exactly once.  This is
78 equivalent to using \fBpthread_once()\fR to call a onetime initialization
79 function that calls \fBthr_keycreate()\fR to create the data key.
80 .SS "Set Value"
81 .sp
82 .LP
83 Once a key has been created, each thread can bind a new \fIvalue\fR to the key
84 using \fBthr_setspecific()\fR. The values are unique to the binding thread and
85 are  individually maintained.  These values continue for the life of the
86 calling thread.
87 .sp
88 .LP
89 Proper synchronization of  \fIkey\fR storage and access must be ensured by the
90 caller. The \fIvalue\fR argument to \fBthr_setspecific()\fR is generally a
91 pointer to a block of dynamically allocated memory reserved by the calling
92 thread for its own use. See \fBEXAMPLES\fR below.
93 .sp
94 .LP
95 At thread exit, the \fIdestructor\fR function, which is associated at time of
96 creation,   is called and it uses the specific  key value as its sole argument.
97 .SS "Get Value"
98 .sp
99 .LP
100 \fBthr_getspecific()\fR stores the current value bound to \fIkey\fR for the
101 calling thread into the location pointed to by \fIvaluep\fR.
102 .SH RETURN VALUES
105 If successful, \fBthr_keycreate()\fR, \fBthr_keycreate_once()\fR,
106 \fBthr_setspecific()\fR and \fBthr_getspecific()\fR return 0. Otherwise, an
107 error number is returned to indicate the error.
108 .SH ERRORS
111 If the following conditions occur, \fBthr_keycreate()\fR and
112 \fBthr_keycreate_once()\fR return the corresponding error number:
114 .ne 2
116 \fB\fBEAGAIN\fR\fR
118 .RS 10n
119 The system lacked the necessary resources to create another thread-specific
120 data key.
124 .ne 2
126 \fB\fBENOMEM\fR\fR
128 .RS 10n
129 Insufficient memory exists to create the key.
134 If the following conditions occur, \fBthr_setspecific()\fR returns the
135 corresponding error number:
137 .ne 2
139 \fB\fBENOMEM\fR\fR
141 .RS 10n
142 Insufficient memory exists to associate the value with the key.
147 The \fBthr_setspecific()\fR function returns the corresponding error number:
149 .ne 2
151 \fB\fBEINVAL\fR\fR
153 .RS 10n
154 The \fIkey\fR value is invalid.
157 .SH EXAMPLES
159 \fBExample 1 \fRCall the thread-specific data from more than one thread without
160 special initialization.
163 In this example, the thread-specific data in this function can be called from
164 more than one thread without special initialization. For each argument passed
165 to the executable,  a thread is created and privately bound to the string-value
166 of that argument.
169 .in +2
171 /* cc -mt thisfile.c */
173 #include <stdio.h>
174 #include <stdlib.h>
175 #include <string.h>
176 #include <thread.h>
178 void *thread_specific_data(void *);
179 void cleanup(void*);
180 #define MAX_ARGC 20
181 thread_t tid[MAX_ARGC];
182 int num_threads;
185 main(int argc, char *argv[]) {
186   int i;
187   num_threads = argc - 1;
188   for (i = 0; i < num_threads; i++)
189      thr_create(NULL, 0, thread_specific_data, argv[i+1], 0, &tid[i]);
190   for (i = 0; i < num_threads; i++)
191      thr_join(tid[i], NULL, NULL);
192   return (0);
193 } /* end main */
195 void *
196 thread_specific_data(void *arg) {
197   static thread_key_t key = THR_ONCE_KEY;
198   char *private_data = arg;
199   void *tsd = NULL;
200   void *data;
202   thr_keycreate_once(&key, cleanup);
203   thr_getspecific(key, &tsd);
204   if (tsd == NULL) {
205        data = malloc(strlen(private_data) + 1);
206        strcpy(data, private_data);
207        thr_setspecific(key, data);
208        thr_getspecific(key, &tsd);
209   }
210   printf("tsd for %d = %s\en", thr_self(), (char *)tsd);
211   thr_getspecific(key, &tsd);
212   printf("tsd for %d remains %s\en", thr_self(), (char *)tsd);
213   return (NULL);
214 } /* end thread_specific_data */
216 void
217 cleanup(void *v) {
218   /* application-specific clean-up function */
219   free(v);
222 .in -2
224 .SH ATTRIBUTES
227 See \fBattributes\fR(5) for descriptions of the following attributes:
232 box;
233 c | c
234 l | l .
235 ATTRIBUTE TYPE  ATTRIBUTE VALUE
237 Interface Stability     Committed
239 MT-Level        MT-Safe
242 .SH SEE ALSO
245 \fBpthread_once\fR(3C), \fBthr_exit\fR(3C), \fBattributes\fR(5),
246 \fBstandards\fR(5)
247 .SH WARNINGS
250 The  \fBthr_getspecific()\fR and \fBthr_setspecific()\fR functions can be
251 called either explicitly or implicitly from a thread-specific data destructor
252 function. Calling \fBthr_setspecific()\fR from a destructor can result in lost
253 storage or infinite loops.