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 | |