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
36typedef __int64 tsrm_intptr_t;
37typedef unsigned __int64 tsrm_uintptr_t;
38#else
39typedef long tsrm_intptr_t;
40typedef 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
63typedef 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
86typedef 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
97typedef void (*ts_allocate_ctor)(void *, void ***);
98typedef void (*ts_allocate_dtor)(void *, void ***);
99
100#define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
101
102#ifdef __cplusplus
103extern "C" {
104#endif
105
106/* startup/shutdown */
107TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename);
108TSRM_API void tsrm_shutdown(void);
109
110/* allocates a new thread-safe-resource id */
111TSRM_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 */
114TSRM_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 */
118TSRM_API void ts_free_thread(void);
119
120/* frees all resources allocated for all threads except current */
121void ts_free_worker_threads(void);
122
123/* deallocates all occurrences of a given id */
124TSRM_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
132typedef void (*tsrm_thread_begin_func_t)(THREAD_T thread_id, void ***tsrm_ls);
133typedef void (*tsrm_thread_end_func_t)(THREAD_T thread_id, void ***tsrm_ls);
134
135
136TSRM_API int tsrm_error(int level, const char *format, ...);
137TSRM_API void tsrm_error_set(int level, char *debug_filename);
138
139/* utility functions */
140TSRM_API THREAD_T tsrm_thread_id(void);
141TSRM_API MUTEX_T tsrm_mutex_alloc(void);
142TSRM_API void tsrm_mutex_free(MUTEX_T mutexp);
143TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp);
144TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp);
145#ifdef HAVE_SIGPROCMASK
146TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset);
147#endif
148
149TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler);
150TSRM_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. */
154TSRM_API void *tsrm_new_interpreter_context(void);
155TSRM_API void *tsrm_set_interpreter_context(void *new_ctx);
156TSRM_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