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 #ifdef TSRM_WIN32 24 # ifdef TSRM_EXPORTS 25 # define TSRM_API __declspec(dllexport) 26 # else 27 # define TSRM_API __declspec(dllimport) 28 # endif 29 #elif defined(__GNUC__) && __GNUC__ >= 4 30 # define TSRM_API __attribute__ ((visibility("default"))) 31 #else 32 # define TSRM_API 33 #endif 34 35 #ifdef _WIN64 36 typedef __int64 tsrm_intptr_t; 37 typedef unsigned __int64 tsrm_uintptr_t; 38 #else 39 typedef long tsrm_intptr_t; 40 typedef unsigned long tsrm_uintptr_t; 41 #endif 42 43 /* Only compile multi-threading functions if we're in ZTS mode */ 44 #ifdef ZTS 45 46 #ifdef TSRM_WIN32 47 # ifndef TSRM_INCLUDE_FULL_WINDOWS_HEADERS 48 # define WIN32_LEAN_AND_MEAN 49 # endif 50 # include <windows.h> 51 # include <shellapi.h> 52 #elif defined(GNUPTH) 53 # include <pth.h> 54 #elif defined(PTHREADS) 55 # include <pthread.h> 56 #elif defined(TSRM_ST) 57 # include <st.h> 58 #elif defined(BETHREADS) 59 #include <kernel/OS.h> 60 #include <TLS.h> 61 #endif 62 63 typedef int ts_rsrc_id; 64 65 /* Define THREAD_T and MUTEX_T */ 66 #ifdef TSRM_WIN32 67 # define THREAD_T DWORD 68 # define MUTEX_T CRITICAL_SECTION * 69 #elif defined(GNUPTH) 70 # define THREAD_T pth_t 71 # define MUTEX_T pth_mutex_t * 72 #elif defined(PTHREADS) 73 # define THREAD_T pthread_t 74 # define MUTEX_T pthread_mutex_t * 75 #elif defined(NSAPI) 76 # define THREAD_T SYS_THREAD 77 # define MUTEX_T CRITICAL 78 #elif defined(PI3WEB) 79 # define THREAD_T PIThread * 80 # define MUTEX_T PISync * 81 #elif defined(TSRM_ST) 82 # define THREAD_T st_thread_t 83 # define MUTEX_T st_mutex_t 84 #elif defined(BETHREADS) 85 # define THREAD_T thread_id 86 typedef struct { 87 sem_id sem; 88 int32 ben; 89 } beos_ben; 90 # define MUTEX_T beos_ben * 91 #endif 92 93 #ifdef HAVE_SIGNAL_H 94 #include <signal.h> 95 #endif 96 97 typedef void (*ts_allocate_ctor)(void *, void ***); 98 typedef void (*ts_allocate_dtor)(void *, void ***); 99 100 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts 101 102 #ifdef __cplusplus 103 extern "C" { 104 #endif 105 106 /* startup/shutdown */ 107 TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename); 108 TSRM_API void tsrm_shutdown(void); 109 110 /* allocates a new thread-safe-resource id */ 111 TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor); 112 113 /* fetches the requested resource for the current thread */ 114 TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id); 115 #define ts_resource(id) ts_resource_ex(id, NULL) 116 117 /* frees all resources allocated for the current thread */ 118 TSRM_API void ts_free_thread(void); 119 120 /* frees all resources allocated for all threads except current */ 121 void ts_free_worker_threads(void); 122 123 /* deallocates all occurrences of a given id */ 124 TSRM_API void ts_free_id(ts_rsrc_id id); 125 126 127 /* Debug support */ 128 #define TSRM_ERROR_LEVEL_ERROR 1 129 #define TSRM_ERROR_LEVEL_CORE 2 130 #define TSRM_ERROR_LEVEL_INFO 3 131 132 typedef void (*tsrm_thread_begin_func_t)(THREAD_T thread_id, void ***tsrm_ls); 133 typedef void (*tsrm_thread_end_func_t)(THREAD_T thread_id, void ***tsrm_ls); 134 135 136 TSRM_API int tsrm_error(int level, const char *format, ...); 137 TSRM_API void tsrm_error_set(int level, char *debug_filename); 138 139 /* utility functions */ 140 TSRM_API THREAD_T tsrm_thread_id(void); 141 TSRM_API MUTEX_T tsrm_mutex_alloc(void); 142 TSRM_API void tsrm_mutex_free(MUTEX_T mutexp); 143 TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp); 144 TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp); 145 #ifdef HAVE_SIGPROCMASK 146 TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset); 147 #endif 148 149 TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler); 150 TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler); 151 152 /* these 3 APIs should only be used by people that fully understand the threading model 153 * used by PHP/Zend and the selected SAPI. */ 154 TSRM_API void *tsrm_new_interpreter_context(void); 155 TSRM_API void *tsrm_set_interpreter_context(void *new_ctx); 156 TSRM_API void tsrm_free_interpreter_context(void *context); 157 158 #define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1) 159 #define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1) 160 161 #define TSRMLS_FETCH() void ***tsrm_ls = (void ***) ts_resource_ex(0, NULL) 162 #define TSRMLS_FETCH_FROM_CTX(ctx) void ***tsrm_ls = (void ***) ctx 163 #define TSRMLS_SET_CTX(ctx) ctx = (void ***) tsrm_ls 164 #define TSRMG(id, type, element) (((type) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element) 165 #define TSRMLS_D void ***tsrm_ls 166 #define TSRMLS_DC , TSRMLS_D 167 #define TSRMLS_C tsrm_ls 168 #define TSRMLS_CC , TSRMLS_C 169 170 #ifdef __cplusplus 171 } 172 #endif 173 174 #else /* non ZTS */ 175 176 #define TSRMLS_FETCH() 177 #define TSRMLS_FETCH_FROM_CTX(ctx) 178 #define TSRMLS_SET_CTX(ctx) 179 #define TSRMLS_D void 180 #define TSRMLS_DC 181 #define TSRMLS_C 182 #define TSRMLS_CC 183 184 #endif /* ZTS */ 185 186 #endif /* TSRM_H */ 187