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@php.net> | 10 +----------------------------------------------------------------------+ 11 */ 12 13 #ifndef TSRM_H 14 #define TSRM_H 15 16 #if !defined(__CYGWIN__) && defined(WIN32) 17 # define TSRM_WIN32 18 # include "Zend/zend_config.w32.h" 19 #else 20 # include "main/php_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 #else 48 # include <pthread.h> 49 #endif 50 51 #if SIZEOF_SIZE_T == 4 52 # define TSRM_ALIGNED_SIZE(size) \ 53 (((size) + INT32_C(15)) & ~INT32_C(15)) 54 #else 55 # define TSRM_ALIGNED_SIZE(size) \ 56 (((size) + INT64_C(15)) & ~INT64_C(15)) 57 #endif 58 59 typedef int ts_rsrc_id; 60 61 /* Define THREAD_T and MUTEX_T */ 62 #ifdef TSRM_WIN32 63 # define THREAD_T DWORD 64 # define MUTEX_T CRITICAL_SECTION * 65 #else 66 # define THREAD_T pthread_t 67 # define MUTEX_T pthread_mutex_t * 68 #endif 69 70 #include <signal.h> 71 72 typedef void (*ts_allocate_ctor)(void *); 73 typedef void (*ts_allocate_dtor)(void *); 74 75 #define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts 76 77 #ifdef __cplusplus 78 extern "C" { 79 #endif 80 81 /* startup/shutdown */ 82 TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, const char *debug_filename); 83 TSRM_API void tsrm_shutdown(void); 84 85 /* environ lock API */ 86 TSRM_API void tsrm_env_lock(void); 87 TSRM_API void tsrm_env_unlock(void); 88 89 /* allocates a new thread-safe-resource id */ 90 TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor); 91 92 /* Fast resource in reserved (pre-allocated) space */ 93 TSRM_API void tsrm_reserve(size_t size); 94 TSRM_API ts_rsrc_id ts_allocate_fast_id(ts_rsrc_id *rsrc_id, size_t *offset, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor); 95 96 /* fetches the requested resource for the current thread */ 97 TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id); 98 #define ts_resource(id) ts_resource_ex(id, NULL) 99 100 /* frees all resources allocated for the current thread */ 101 TSRM_API void ts_free_thread(void); 102 103 /* deallocates all occurrences of a given id */ 104 TSRM_API void ts_free_id(ts_rsrc_id id); 105 106 107 /* Debug support */ 108 #define TSRM_ERROR_LEVEL_ERROR 1 109 #define TSRM_ERROR_LEVEL_CORE 2 110 #define TSRM_ERROR_LEVEL_INFO 3 111 112 typedef void (*tsrm_thread_begin_func_t)(THREAD_T thread_id); 113 typedef void (*tsrm_thread_end_func_t)(THREAD_T thread_id); 114 typedef void (*tsrm_shutdown_func_t)(void); 115 116 117 TSRM_API int tsrm_error(int level, const char *format, ...); 118 TSRM_API void tsrm_error_set(int level, const char *debug_filename); 119 120 /* utility functions */ 121 TSRM_API THREAD_T tsrm_thread_id(void); 122 TSRM_API MUTEX_T tsrm_mutex_alloc(void); 123 TSRM_API void tsrm_mutex_free(MUTEX_T mutexp); 124 TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp); 125 TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp); 126 #ifdef HAVE_SIGPROCMASK 127 TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset); 128 #endif 129 130 TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler); 131 TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler); 132 TSRM_API void *tsrm_set_shutdown_handler(tsrm_shutdown_func_t shutdown_handler); 133 134 TSRM_API void *tsrm_get_ls_cache(void); 135 TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void); 136 TSRM_API uint8_t tsrm_is_main_thread(void); 137 TSRM_API uint8_t tsrm_is_shutdown(void); 138 TSRM_API const char *tsrm_api_name(void); 139 140 #ifdef TSRM_WIN32 141 # define TSRM_TLS __declspec(thread) 142 #else 143 # define TSRM_TLS __thread 144 #endif 145 146 #ifndef __has_attribute 147 # define __has_attribute(x) 0 148 #endif 149 150 #if !__has_attribute(tls_model) || defined(__FreeBSD__) || defined(__MUSL__) || defined(__HAIKU__) 151 # define TSRM_TLS_MODEL_ATTR 152 #elif __PIC__ 153 # define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("initial-exec"))) 154 #else 155 # define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("local-exec"))) 156 #endif 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 TSRMG(id, type, element) (TSRMG_BULK(id, type)->element) 162 #define TSRMG_BULK(id, type) ((type) (*((void ***) tsrm_get_ls_cache()))[TSRM_UNSHUFFLE_RSRC_ID(id)]) 163 #define TSRMG_FAST(offset, type, element) (TSRMG_FAST_BULK(offset, type)->element) 164 #define TSRMG_FAST_BULK(offset, type) ((type) (((char*) tsrm_get_ls_cache())+(offset))) 165 166 #define TSRMG_STATIC(id, type, element) (TSRMG_BULK_STATIC(id, type)->element) 167 #define TSRMG_BULK_STATIC(id, type) ((type) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(id)]) 168 #define TSRMG_FAST_STATIC(offset, type, element) (TSRMG_FAST_BULK_STATIC(offset, type)->element) 169 #define TSRMG_FAST_BULK_STATIC(offset, type) ((type) (((char*) TSRMLS_CACHE)+(offset))) 170 #define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR; 171 #define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR = NULL; 172 #define TSRMLS_CACHE_UPDATE() TSRMLS_CACHE = tsrm_get_ls_cache() 173 #define TSRMLS_CACHE _tsrm_ls_cache 174 175 #ifdef __cplusplus 176 } 177 #endif 178 179 #else /* non ZTS */ 180 181 #define tsrm_env_lock() 182 #define tsrm_env_unlock() 183 184 #define TSRMG_STATIC(id, type, element) 185 #define TSRMLS_CACHE_EXTERN() 186 #define TSRMLS_CACHE_DEFINE() 187 #define TSRMLS_CACHE_UPDATE() 188 #define TSRMLS_CACHE 189 190 #define TSRM_TLS 191 192 #endif /* ZTS */ 193 194 #endif /* TSRM_H */ 195