| 1 | /*
|
|---|
| 2 | Unix SMB/CIFS implementation.
|
|---|
| 3 | SMB thread interface functions.
|
|---|
| 4 | Copyright (C) Jeremy Allison, 2009.
|
|---|
| 5 |
|
|---|
| 6 | This program is free software; you can redistribute it and/or modify
|
|---|
| 7 | it under the terms of the GNU General Public License as published by
|
|---|
| 8 | the Free Software Foundation; either version 3 of the License, or
|
|---|
| 9 | (at your option) any later version.
|
|---|
| 10 |
|
|---|
| 11 | This program is distributed in the hope that it will be useful,
|
|---|
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|---|
| 14 | GNU General Public License for more details.
|
|---|
| 15 |
|
|---|
| 16 | You should have received a copy of the GNU General Public License
|
|---|
| 17 | along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|---|
| 18 | */
|
|---|
| 19 |
|
|---|
| 20 | #ifndef _smb_threads_h_
|
|---|
| 21 | #define _smb_threads_h_
|
|---|
| 22 |
|
|---|
| 23 | typedef bool smb_thread_once_t;
|
|---|
| 24 | #define SMB_THREAD_ONCE_INIT false
|
|---|
| 25 |
|
|---|
| 26 | enum smb_thread_lock_type {
|
|---|
| 27 | SMB_THREAD_LOCK = 1,
|
|---|
| 28 | SMB_THREAD_UNLOCK
|
|---|
| 29 | };
|
|---|
| 30 |
|
|---|
| 31 | struct smb_thread_functions {
|
|---|
| 32 | /* Mutex and tls functions. */
|
|---|
| 33 | int (*create_mutex)(const char *lockname,
|
|---|
| 34 | void **pplock,
|
|---|
| 35 | const char *location);
|
|---|
| 36 | void (*destroy_mutex)(void *plock,
|
|---|
| 37 | const char *location);
|
|---|
| 38 | int (*lock_mutex)(void *plock,
|
|---|
| 39 | int lock_type,
|
|---|
| 40 | const char *location);
|
|---|
| 41 |
|
|---|
| 42 | /* Thread local storage. */
|
|---|
| 43 | int (*create_tls)(const char *keyname,
|
|---|
| 44 | void **ppkey,
|
|---|
| 45 | const char *location);
|
|---|
| 46 | void (*destroy_tls)(void **pkey,
|
|---|
| 47 | const char *location);
|
|---|
| 48 | int (*set_tls)(void *pkey, const void *pval, const char *location);
|
|---|
| 49 | void *(*get_tls)(void *pkey, const char *location);
|
|---|
| 50 | };
|
|---|
| 51 |
|
|---|
| 52 | int smb_thread_set_functions(const struct smb_thread_functions *tf);
|
|---|
| 53 | int smb_thread_once(smb_thread_once_t *ponce,
|
|---|
| 54 | void (*init_fn)(void *pdata),
|
|---|
| 55 | void *pdata);
|
|---|
| 56 |
|
|---|
| 57 | extern const struct smb_thread_functions *global_tfp;
|
|---|
| 58 |
|
|---|
| 59 | /* Define the pthread version of the functions. */
|
|---|
| 60 |
|
|---|
| 61 | #define SMB_THREADS_DEF_PTHREAD_IMPLEMENTATION(tf) \
|
|---|
| 62 | \
|
|---|
| 63 | static int smb_create_mutex_pthread(const char *lockname, void **pplock, const char *location) \
|
|---|
| 64 | { \
|
|---|
| 65 | pthread_mutex_t *pmut = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); \
|
|---|
| 66 | if (!pmut) { \
|
|---|
| 67 | return ENOMEM; \
|
|---|
| 68 | } \
|
|---|
| 69 | pthread_mutex_init(pmut, NULL); \
|
|---|
| 70 | *pplock = (void *)pmut; \
|
|---|
| 71 | return 0; \
|
|---|
| 72 | } \
|
|---|
| 73 | \
|
|---|
| 74 | static void smb_destroy_mutex_pthread(void *plock, const char *location) \
|
|---|
| 75 | { \
|
|---|
| 76 | pthread_mutex_destroy((pthread_mutex_t *)plock); \
|
|---|
| 77 | free(plock); \
|
|---|
| 78 | } \
|
|---|
| 79 | \
|
|---|
| 80 | static int smb_lock_pthread(void *plock, int lock_type, const char *location) \
|
|---|
| 81 | { \
|
|---|
| 82 | if (lock_type == SMB_THREAD_UNLOCK) { \
|
|---|
| 83 | return pthread_mutex_unlock((pthread_mutex_t *)plock); \
|
|---|
| 84 | } else { \
|
|---|
| 85 | return pthread_mutex_lock((pthread_mutex_t *)plock); \
|
|---|
| 86 | } \
|
|---|
| 87 | } \
|
|---|
| 88 | \
|
|---|
| 89 | static int smb_create_tls_pthread(const char *keyname, void **ppkey, const char *location) \
|
|---|
| 90 | { \
|
|---|
| 91 | int ret; \
|
|---|
| 92 | pthread_key_t *pkey; \
|
|---|
| 93 | pkey = (pthread_key_t *)malloc(sizeof(pthread_key_t)); \
|
|---|
| 94 | if (!pkey) { \
|
|---|
| 95 | return ENOMEM; \
|
|---|
| 96 | } \
|
|---|
| 97 | ret = pthread_key_create(pkey, NULL); \
|
|---|
| 98 | if (ret) { \
|
|---|
| 99 | free(pkey); \
|
|---|
| 100 | return ret; \
|
|---|
| 101 | } \
|
|---|
| 102 | *ppkey = (void *)pkey; \
|
|---|
| 103 | return 0; \
|
|---|
| 104 | } \
|
|---|
| 105 | \
|
|---|
| 106 | static void smb_destroy_tls_pthread(void **ppkey, const char *location) \
|
|---|
| 107 | { \
|
|---|
| 108 | if (*ppkey) { \
|
|---|
| 109 | pthread_key_delete(*(pthread_key_t *)ppkey); \
|
|---|
| 110 | free(*ppkey); \
|
|---|
| 111 | *ppkey = NULL; \
|
|---|
| 112 | } \
|
|---|
| 113 | } \
|
|---|
| 114 | \
|
|---|
| 115 | static int smb_set_tls_pthread(void *pkey, const void *pval, const char *location) \
|
|---|
| 116 | { \
|
|---|
| 117 | return pthread_setspecific(*(pthread_key_t *)pkey, pval); \
|
|---|
| 118 | } \
|
|---|
| 119 | \
|
|---|
| 120 | static void *smb_get_tls_pthread(void *pkey, const char *location) \
|
|---|
| 121 | { \
|
|---|
| 122 | return pthread_getspecific(*(pthread_key_t *)pkey); \
|
|---|
| 123 | } \
|
|---|
| 124 | \
|
|---|
| 125 | static const struct smb_thread_functions (tf) = { \
|
|---|
| 126 | smb_create_mutex_pthread, \
|
|---|
| 127 | smb_destroy_mutex_pthread, \
|
|---|
| 128 | smb_lock_pthread, \
|
|---|
| 129 | smb_create_tls_pthread, \
|
|---|
| 130 | smb_destroy_tls_pthread, \
|
|---|
| 131 | smb_set_tls_pthread, \
|
|---|
| 132 | smb_get_tls_pthread }
|
|---|
| 133 |
|
|---|
| 134 | #endif
|
|---|