xref: /dragonfly/lib/libc/include/nss_tls.h (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
1 /*-
2  * Copyright (c) 2003 Networks Associates Technology, Inc.
3  * All rights reserved.
4  *
5  * This software was developed for the FreeBSD Project by
6  * Jacques A. Vidrine, Safeport Network Services, and Network
7  * Associates Laboratories, the Security Research Division of Network
8  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035
9  * ("CBOSS"), as part of the DARPA CHATS research program.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * $FreeBSD: src/lib/libc/include/nss_tls.h,v 1.3 2004/03/30 15:56:15 nectar Exp $
33  *
34  * Macros which generate thread local storage handling code in NSS modules.
35  */
36 #ifndef _NSS_TLS_H_
37 #define _NSS_TLS_H_
38 
39 #define NSS_TLS_HANDLING(name)                                                  \
40 static pthread_key_t name##_state_key;                                \
41 static    void       name##_keyinit(void);                                      \
42 static    int        name##_getstate(struct name##_state **);         \
43 \
44 static void                                                                               \
45 name##_keyinit(void)                                                                      \
46 {                                                                                         \
47           _pthread_key_create(&name##_state_key, name##_endstate);    \
48 }                                                                                         \
49 \
50 static int                                                                      \
51 name##_getstate(struct name##_state **p)                              \
52 {                                                                               \
53           static struct name##_state st;                                        \
54           static pthread_once_t         keyinit = PTHREAD_ONCE_INIT;  \
55           int                           rv;                                     \
56                                                                                 \
57           if (!__isthreaded || _pthread_main_np() != 0) {             \
58                     *p = &st;                                         \
59                     return (0);                                                 \
60           }                                                                     \
61           rv = _pthread_once(&keyinit, name##_keyinit);               \
62           if (rv != 0)                                                          \
63                     return (rv);                                                \
64           *p = _pthread_getspecific(name##_state_key);                \
65           if (*p != NULL)                                                       \
66                     return (0);                                                 \
67           *p = calloc(1, sizeof(**p));                                \
68           if (*p == NULL)                                                       \
69                     return (ENOMEM);                                  \
70           rv = _pthread_setspecific(name##_state_key, *p);  \
71           if (rv != 0) {                                                        \
72                     free(*p);                                         \
73                     *p = NULL;                                                  \
74           }                                                                     \
75           return (rv);                                                          \
76 }                                                                               \
77 /* allow the macro invocation to end with a semicolon */    \
78 struct _clashproof_bmVjdGFy
79 
80 #endif /* _NSS_TLS_H_ */
81