1 /* 2 +----------------------------------------------------------------------+ 3 | Thread Safe Resource Manager | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 1999-2011, Andi Gutmans, Sascha Schumann, Zeev Suraski | 6 | This source file is subject to the TSRM license, that is bundled | 7 | with this package in the file LICENSE | 8 +----------------------------------------------------------------------+ 9 | Authors: Zeev Suraski <zeev@zend.com> | 10 +----------------------------------------------------------------------+ 11 */ 12 13 #ifndef TSRM_H 14 #define TSRM_H 15 16 #if !defined(__CYGWIN__) && defined(WIN32) 17 # define TSRM_WIN32 18 # include "tsrm_config.w32.h" 19 #else 20 # include <tsrm_config.h> 21 #endif 22 23 #include "main/php_stdint.h" 24 25 #ifdef TSRM_WIN32 26 # ifdef TSRM_EXPORTS 27 # define TSRM_API __declspec(dllexport) 28 # else 29 # define TSRM_API __declspec(dllimport) 30 # endif 31 #elif defined(__GNUC__) && __GNUC__ >= 4 32 # define TSRM_API __attribute__ ((visibility("default"))) 33 #else 34 # define TSRM_API 35 #endif 36 37 typedef intptr_t tsrm_intptr_t; 38 typedef uintptr_t tsrm_uintptr_t; 39 40 /* Only compile multi-threading functions if we're in ZTS mode */ 41 #ifdef ZTS 42 43 #ifdef TSRM_WIN32 44 # ifndef TSRM_INCLUDE_FULL_WINDOWS_HEADERS 45 # define WIN32_LEAN_AND_MEAN 46 # endif 47 # include <windows.h> 48 # include <shellapi.h> 49 #elif defined(GNUPTH) 50 # include <pth.h> 51 #elif defined(PTHREADS) 52 # include <pthread.h> 53 #elif defined(TSRM_ST) 54 # include <st.h> 55 #elif defined(BETHREADS) 56 #include <kernel/OS.h> 57 #include <TLS.h> 58 #endif 59 60 typedef int ts_rsrc_id; 61 62 /* Define THREAD_T and MUTEX_T */ 63 #ifdef TSRM_WIN32 64 # define THREAD_T DWORD 65 # define MUTEX_T CRITICAL_SECTION * 66 #elif defined(GNUPTH) 67 # define THREAD_T pth_t 68 # define MUTEX_T pth_mutex_t * 69 #elif defined(PTHREADS) 70 # define THREAD_T pthread_t 71 # define MUTEX_T pthread_mutex_t * 72 #elif defined(NSAPI) 73 # define THREAD_T SYS_THREAD 74 # define MUTEX_T CRITICAL 75 #elif defined(PI3WEB) 76 # define THREAD_T PIThread * 77 # define MUTEX_T PISync * 78 #elif defined(TSRM_ST) 79 # define THREAD_T st_thread_t 80 # define MUTEX_T st_mutex_t 81 #elif defined(BETHREADS) 82 # define THREAD_T thread_id 83 typedef struct { 84 sem_id sem; 85 int32 ben; 86 } beos_ben; 87 # define MUTEX_T beos_ben * 88 #endif 89 90 #ifdef HAVE_SIGNAL_H 91 #include <signal.h> 92 #endif 93 94 typedef void (*ts_allocate_ctor)(void *); 95 typedef void (*ts_allocate_dtor)(void *); 96 97 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts 98 99 #ifdef __cplusplus 100 extern "C" { 101 #endif 102 103 /* startup/shutdown */ 104 TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename); 105 TSRM_API void tsrm_shutdown(void); 106 107 /* allocates a new thread-safe-resource id */ 108 TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor); 109 110 /* fetches the requested resource for the current thread */ 111 TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id); 112 #define ts_resource(id) ts_resource_ex(id, NULL) 113 114 /* frees all resources allocated for the current thread */ 115 TSRM_API void ts_free_thread(void); 116 117 /* frees all resources allocated for all threads except current */ 118 void ts_free_worker_threads(void); 119 120 /* deallocates all occurrences of a given id */ 121 TSRM_API void ts_free_id(ts_rsrc_id id); 122 123 124 /* Debug support */ 125 #define TSRM_ERROR_LEVEL_ERROR 1 126 #define TSRM_ERROR_LEVEL_CORE 2 127 #define TSRM_ERROR_LEVEL_INFO 3 128 129 typedef void (*tsrm_thread_begin_func_t)(THREAD_T thread_id); 130 typedef void (*tsrm_thread_end_func_t)(THREAD_T thread_id); 131 typedef void (*tsrm_shutdown_func_t)(void); 132 133 134 TSRM_API int tsrm_error(int level, const char *format, ...); 135 TSRM_API void tsrm_error_set(int level, char *debug_filename); 136 137 /* utility functions */ 138 TSRM_API THREAD_T tsrm_thread_id(void); 139 TSRM_API MUTEX_T tsrm_mutex_alloc(void); 140 TSRM_API void tsrm_mutex_free(MUTEX_T mutexp); 141 TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp); 142 TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp); 143 #ifdef HAVE_SIGPROCMASK 144 TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset); 145 #endif 146 147 TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler); 148 TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler); 149 TSRM_API void *tsrm_set_shutdown_handler(tsrm_shutdown_func_t shutdown_handler); 150 151 /* these 3 APIs should only be used by people that fully understand the threading model 152 * used by PHP/Zend and the selected SAPI. */ 153 TSRM_API void *tsrm_new_interpreter_context(void); 154 TSRM_API void *tsrm_set_interpreter_context(void *new_ctx); 155 TSRM_API void tsrm_free_interpreter_context(void *context); 156 157 TSRM_API void *tsrm_get_ls_cache(void); 158 TSRM_API uint8_t tsrm_is_main_thread(void); 159 160 #if defined(__cplusplus) && __cplusplus > 199711L 161 # define TSRM_TLS thread_local 162 #else 163 # ifdef TSRM_WIN32 164 # define TSRM_TLS __declspec(thread) 165 # else 166 # define TSRM_TLS __thread 167 # endif 168 #endif 169 170 #define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1) 171 #define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1) 172 173 #define TSRMLS_FETCH_FROM_CTX(ctx) void ***tsrm_ls = (void ***) ctx 174 #define TSRMLS_SET_CTX(ctx) ctx = (void ***) tsrm_get_ls_cache() 175 #define TSRMG(id, type, element) (TSRMG_BULK(id, type)->element) 176 #define TSRMG_BULK(id, type) ((type) (*((void ***) tsrm_get_ls_cache()))[TSRM_UNSHUFFLE_RSRC_ID(id)]) 177 178 #define TSRMG_STATIC(id, type, element) (TSRMG_BULK_STATIC(id, type)->element) 179 #define TSRMG_BULK_STATIC(id, type) ((type) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(id)]) 180 #define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE; 181 #define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE = NULL; 182 #define TSRMLS_CACHE_UPDATE() TSRMLS_CACHE = tsrm_get_ls_cache() 183 #define TSRMLS_CACHE _tsrm_ls_cache 184 185 /* BC only */ 186 #define TSRMLS_D void 187 #define TSRMLS_DC 188 #define TSRMLS_C 189 #define TSRMLS_CC 190 #define TSRMLS_FETCH() 191 192 #ifdef __cplusplus 193 } 194 #endif 195 196 #else /* non ZTS */ 197 198 #define TSRMLS_FETCH() 199 #define TSRMLS_FETCH_FROM_CTX(ctx) 200 #define TSRMLS_SET_CTX(ctx) 201 202 #define TSRMG_STATIC(id, type, element) 203 #define TSRMLS_CACHE_EXTERN() 204 #define TSRMLS_CACHE_DEFINE() 205 #define TSRMLS_CACHE_UPDATE() 206 #define TSRMLS_CACHE 207 208 #define TSRM_TLS 209 210 /* BC only */ 211 #define TSRMLS_D void 212 #define TSRMLS_DC 213 #define TSRMLS_C 214 #define TSRMLS_CC 215 216 #endif /* ZTS */ 217 218 #endif /* TSRM_H */ 219 220 /* 221 * Local variables: 222 * tab-width: 4 223 * c-basic-offset: 4 224 * End: 225 * vim600: sw=4 ts=4 fdm=marker 226 * vim<600: sw=4 ts=4 227 */ 228