1999-04-23 19:00:02 +08:00
|
|
|
/*
|
|
|
|
+----------------------------------------------------------------------+
|
|
|
|
| Thread Safe Resource Manager |
|
|
|
|
+----------------------------------------------------------------------+
|
2011-01-01 10:17:06 +08:00
|
|
|
| Copyright (c) 1999-2011, Andi Gutmans, Sascha Schumann, Zeev Suraski |
|
2000-09-01 03:02:14 +08:00
|
|
|
| This source file is subject to the TSRM license, that is bundled |
|
|
|
|
| with this package in the file LICENSE |
|
1999-04-23 19:00:02 +08:00
|
|
|
+----------------------------------------------------------------------+
|
2000-09-01 03:02:14 +08:00
|
|
|
| Authors: Zeev Suraski <zeev@zend.com> |
|
1999-04-23 19:00:02 +08:00
|
|
|
+----------------------------------------------------------------------+
|
|
|
|
*/
|
|
|
|
|
2000-07-03 07:16:54 +08:00
|
|
|
#ifndef TSRM_H
|
|
|
|
#define TSRM_H
|
1999-04-21 07:58:02 +08:00
|
|
|
|
2007-02-16 03:11:48 +08:00
|
|
|
#if !defined(__CYGWIN__) && defined(WIN32)
|
2001-07-28 20:16:43 +08:00
|
|
|
# define TSRM_WIN32
|
2002-08-07 22:47:42 +08:00
|
|
|
# include "tsrm_config.w32.h"
|
2007-02-16 03:11:48 +08:00
|
|
|
#else
|
|
|
|
# include <tsrm_config.h>
|
2001-07-28 20:16:43 +08:00
|
|
|
#endif
|
2001-07-28 18:46:11 +08:00
|
|
|
|
|
|
|
#ifdef TSRM_WIN32
|
|
|
|
# ifdef TSRM_EXPORTS
|
2008-01-30 17:41:12 +08:00
|
|
|
# define TSRM_API __declspec(dllexport)
|
2001-07-28 18:46:11 +08:00
|
|
|
# else
|
2008-01-30 17:41:12 +08:00
|
|
|
# define TSRM_API __declspec(dllimport)
|
2001-07-28 18:46:11 +08:00
|
|
|
# endif
|
2008-01-30 17:41:12 +08:00
|
|
|
#elif defined(__GNUC__) && __GNUC__ >= 4
|
|
|
|
# define TSRM_API __attribute__ ((visibility("default")))
|
2001-07-28 18:46:11 +08:00
|
|
|
#else
|
|
|
|
# define TSRM_API
|
|
|
|
#endif
|
|
|
|
|
2007-04-16 16:09:56 +08:00
|
|
|
#ifdef _WIN64
|
2007-04-17 14:26:32 +08:00
|
|
|
typedef __int64 tsrm_intptr_t;
|
|
|
|
typedef unsigned __int64 tsrm_uintptr_t;
|
2007-04-16 16:09:56 +08:00
|
|
|
#else
|
|
|
|
typedef long tsrm_intptr_t;
|
|
|
|
typedef unsigned long tsrm_uintptr_t;
|
|
|
|
#endif
|
|
|
|
|
2000-09-01 07:44:10 +08:00
|
|
|
/* Only compile multi-threading functions if we're in ZTS mode */
|
|
|
|
#ifdef ZTS
|
|
|
|
|
2000-09-02 23:03:19 +08:00
|
|
|
#ifdef TSRM_WIN32
|
2003-06-25 13:05:06 +08:00
|
|
|
# ifndef TSRM_INCLUDE_FULL_WINDOWS_HEADERS
|
|
|
|
# define WIN32_LEAN_AND_MEAN
|
|
|
|
# endif
|
1999-04-24 17:01:30 +08:00
|
|
|
# include <windows.h>
|
2003-12-03 22:26:41 +08:00
|
|
|
# include <shellapi.h>
|
1999-12-06 05:55:43 +08:00
|
|
|
#elif defined(GNUPTH)
|
|
|
|
# include <pth.h>
|
1999-04-24 17:01:30 +08:00
|
|
|
#elif defined(PTHREADS)
|
|
|
|
# include <pthread.h>
|
2001-06-22 00:54:05 +08:00
|
|
|
#elif defined(TSRM_ST)
|
|
|
|
# include <st.h>
|
2002-10-05 19:26:17 +08:00
|
|
|
#elif defined(BETHREADS)
|
|
|
|
#include <kernel/OS.h>
|
|
|
|
#include <TLS.h>
|
1999-04-24 17:01:30 +08:00
|
|
|
#endif
|
1999-04-21 07:58:02 +08:00
|
|
|
|
|
|
|
typedef int ts_rsrc_id;
|
|
|
|
|
|
|
|
/* Define THREAD_T and MUTEX_T */
|
2000-09-02 23:03:19 +08:00
|
|
|
#ifdef TSRM_WIN32
|
2014-09-18 17:58:44 +08:00
|
|
|
# define THREAD_T DWORD
|
1999-12-21 04:02:25 +08:00
|
|
|
# define MUTEX_T CRITICAL_SECTION *
|
1999-12-06 05:55:43 +08:00
|
|
|
#elif defined(GNUPTH)
|
1999-12-30 23:52:08 +08:00
|
|
|
# define THREAD_T pth_t
|
1999-12-06 05:55:43 +08:00
|
|
|
# define MUTEX_T pth_mutex_t *
|
1999-04-21 07:58:02 +08:00
|
|
|
#elif defined(PTHREADS)
|
|
|
|
# define THREAD_T pthread_t
|
|
|
|
# define MUTEX_T pthread_mutex_t *
|
|
|
|
#elif defined(NSAPI)
|
|
|
|
# define THREAD_T SYS_THREAD
|
|
|
|
# define MUTEX_T CRITICAL
|
|
|
|
#elif defined(PI3WEB)
|
|
|
|
# define THREAD_T PIThread *
|
|
|
|
# define MUTEX_T PISync *
|
2001-06-22 00:54:05 +08:00
|
|
|
#elif defined(TSRM_ST)
|
|
|
|
# define THREAD_T st_thread_t
|
|
|
|
# define MUTEX_T st_mutex_t
|
2002-10-05 19:26:17 +08:00
|
|
|
#elif defined(BETHREADS)
|
|
|
|
# define THREAD_T thread_id
|
|
|
|
typedef struct {
|
|
|
|
sem_id sem;
|
|
|
|
int32 ben;
|
|
|
|
} beos_ben;
|
|
|
|
# define MUTEX_T beos_ben *
|
1999-04-21 07:58:02 +08:00
|
|
|
#endif
|
|
|
|
|
2011-06-03 05:16:50 +08:00
|
|
|
#ifdef HAVE_SIGNAL_H
|
|
|
|
#include <signal.h>
|
|
|
|
#endif
|
|
|
|
|
2014-12-16 15:03:15 +08:00
|
|
|
typedef void (*ts_allocate_ctor)(void *);
|
|
|
|
typedef void (*ts_allocate_dtor)(void *);
|
reworked the patch, less new stuff but worky
TLS is already used in TSRM, the way exporting the tsrm cache through
a thread local variable is not portable. Additionally, the current
patch suffers from bugs which are hard to find, but prevent it to
be worky with apache. What is done here is mainly uses the idea
from the RFC patch, but
- __thread variable is removed
- offset math and declarations are removed
- extra macros and definitions are removed
What is done merely is
- use an inline function to access the tsrm cache. The function uses
the portable tsrm_tls_get macro which is cheap
- all the TSRM_* macros are set to placebo. Thus this opens the way
remove them later
Except that, the logic is old. TSRMLS_FETCH will have to be done once
per thread, then tsrm_get_ls_cache() can be used. Things seeming to be
worky are cli, cli server and apache. I also tried to enable bz2
shared and it has worked out of the box. The change is yet minimal
diffing to the current master bus is a worky start, IMHO. Though will
have to recheck the other previously done SAPIs - embed and cgi.
The offsets can be added to the tsrm_resource_type struct, then
it'll not be needed to declare them in the userspace. Even the
"done" member type can be changed to int16 or smaller, then adding
the offset as int16 will not change the struct size. As well on the
todo might be removing the hashed storage, thread_id != thread_id and
linked list logic in favour of the explicit TLS operations.
2014-09-26 00:48:27 +08:00
|
|
|
|
1999-10-05 23:15:01 +08:00
|
|
|
#define THREAD_HASH_OF(thr,ts) (unsigned long)thr%(unsigned long)ts
|
1999-04-21 07:58:02 +08:00
|
|
|
|
1999-08-14 17:35:52 +08:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
1999-04-21 07:58:02 +08:00
|
|
|
|
|
|
|
/* startup/shutdown */
|
2000-11-18 10:41:14 +08:00
|
|
|
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, char *debug_filename);
|
1999-12-06 00:21:37 +08:00
|
|
|
TSRM_API void tsrm_shutdown(void);
|
1999-04-21 07:58:02 +08:00
|
|
|
|
|
|
|
/* allocates a new thread-safe-resource id */
|
reworked the patch, less new stuff but worky
TLS is already used in TSRM, the way exporting the tsrm cache through
a thread local variable is not portable. Additionally, the current
patch suffers from bugs which are hard to find, but prevent it to
be worky with apache. What is done here is mainly uses the idea
from the RFC patch, but
- __thread variable is removed
- offset math and declarations are removed
- extra macros and definitions are removed
What is done merely is
- use an inline function to access the tsrm cache. The function uses
the portable tsrm_tls_get macro which is cheap
- all the TSRM_* macros are set to placebo. Thus this opens the way
remove them later
Except that, the logic is old. TSRMLS_FETCH will have to be done once
per thread, then tsrm_get_ls_cache() can be used. Things seeming to be
worky are cli, cli server and apache. I also tried to enable bz2
shared and it has worked out of the box. The change is yet minimal
diffing to the current master bus is a worky start, IMHO. Though will
have to recheck the other previously done SAPIs - embed and cgi.
The offsets can be added to the tsrm_resource_type struct, then
it'll not be needed to declare them in the userspace. Even the
"done" member type can be changed to int16 or smaller, then adding
the offset as int16 will not change the struct size. As well on the
todo might be removing the hashed storage, thread_id != thread_id and
linked list logic in favour of the explicit TLS operations.
2014-09-26 00:48:27 +08:00
|
|
|
TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate_ctor ctor, ts_allocate_dtor dtor);
|
1999-04-21 07:58:02 +08:00
|
|
|
|
|
|
|
/* fetches the requested resource for the current thread */
|
2000-06-16 22:38:05 +08:00
|
|
|
TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id);
|
|
|
|
#define ts_resource(id) ts_resource_ex(id, NULL)
|
1999-04-21 07:58:02 +08:00
|
|
|
|
|
|
|
/* frees all resources allocated for the current thread */
|
1999-12-06 00:21:37 +08:00
|
|
|
TSRM_API void ts_free_thread(void);
|
1999-04-21 07:58:02 +08:00
|
|
|
|
2006-03-14 23:16:07 +08:00
|
|
|
/* frees all resources allocated for all threads except current */
|
|
|
|
void ts_free_worker_threads(void);
|
|
|
|
|
1999-04-21 07:58:02 +08:00
|
|
|
/* deallocates all occurrences of a given id */
|
1999-08-14 17:35:52 +08:00
|
|
|
TSRM_API void ts_free_id(ts_rsrc_id id);
|
1999-04-21 07:58:02 +08:00
|
|
|
|
|
|
|
|
|
|
|
/* Debug support */
|
2000-11-18 07:31:15 +08:00
|
|
|
#define TSRM_ERROR_LEVEL_ERROR 1
|
2000-11-18 10:41:14 +08:00
|
|
|
#define TSRM_ERROR_LEVEL_CORE 2
|
|
|
|
#define TSRM_ERROR_LEVEL_INFO 3
|
2001-07-30 09:46:35 +08:00
|
|
|
|
2014-12-12 15:11:14 +08:00
|
|
|
typedef void (*tsrm_thread_begin_func_t)(THREAD_T thread_id);
|
|
|
|
typedef void (*tsrm_thread_end_func_t)(THREAD_T thread_id);
|
reworked the patch, less new stuff but worky
TLS is already used in TSRM, the way exporting the tsrm cache through
a thread local variable is not portable. Additionally, the current
patch suffers from bugs which are hard to find, but prevent it to
be worky with apache. What is done here is mainly uses the idea
from the RFC patch, but
- __thread variable is removed
- offset math and declarations are removed
- extra macros and definitions are removed
What is done merely is
- use an inline function to access the tsrm cache. The function uses
the portable tsrm_tls_get macro which is cheap
- all the TSRM_* macros are set to placebo. Thus this opens the way
remove them later
Except that, the logic is old. TSRMLS_FETCH will have to be done once
per thread, then tsrm_get_ls_cache() can be used. Things seeming to be
worky are cli, cli server and apache. I also tried to enable bz2
shared and it has worked out of the box. The change is yet minimal
diffing to the current master bus is a worky start, IMHO. Though will
have to recheck the other previously done SAPIs - embed and cgi.
The offsets can be added to the tsrm_resource_type struct, then
it'll not be needed to declare them in the userspace. Even the
"done" member type can be changed to int16 or smaller, then adding
the offset as int16 will not change the struct size. As well on the
todo might be removing the hashed storage, thread_id != thread_id and
linked list logic in favour of the explicit TLS operations.
2014-09-26 00:48:27 +08:00
|
|
|
|
2001-07-30 09:46:35 +08:00
|
|
|
|
2000-11-18 10:41:14 +08:00
|
|
|
TSRM_API int tsrm_error(int level, const char *format, ...);
|
|
|
|
TSRM_API void tsrm_error_set(int level, char *debug_filename);
|
1999-04-21 07:58:02 +08:00
|
|
|
|
|
|
|
/* utility functions */
|
1999-08-14 17:35:52 +08:00
|
|
|
TSRM_API THREAD_T tsrm_thread_id(void);
|
|
|
|
TSRM_API MUTEX_T tsrm_mutex_alloc(void);
|
|
|
|
TSRM_API void tsrm_mutex_free(MUTEX_T mutexp);
|
|
|
|
TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp);
|
|
|
|
TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp);
|
2011-06-03 05:16:50 +08:00
|
|
|
#ifdef HAVE_SIGPROCMASK
|
|
|
|
TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset);
|
|
|
|
#endif
|
1999-08-14 17:35:52 +08:00
|
|
|
|
2001-07-30 09:46:35 +08:00
|
|
|
TSRM_API void *tsrm_set_new_thread_begin_handler(tsrm_thread_begin_func_t new_thread_begin_handler);
|
|
|
|
TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread_end_handler);
|
1999-08-14 17:35:52 +08:00
|
|
|
|
2005-04-28 06:19:54 +08:00
|
|
|
/* these 3 APIs should only be used by people that fully understand the threading model
|
|
|
|
* used by PHP/Zend and the selected SAPI. */
|
|
|
|
TSRM_API void *tsrm_new_interpreter_context(void);
|
|
|
|
TSRM_API void *tsrm_set_interpreter_context(void *new_ctx);
|
|
|
|
TSRM_API void tsrm_free_interpreter_context(void *context);
|
|
|
|
|
reworked the patch, less new stuff but worky
TLS is already used in TSRM, the way exporting the tsrm cache through
a thread local variable is not portable. Additionally, the current
patch suffers from bugs which are hard to find, but prevent it to
be worky with apache. What is done here is mainly uses the idea
from the RFC patch, but
- __thread variable is removed
- offset math and declarations are removed
- extra macros and definitions are removed
What is done merely is
- use an inline function to access the tsrm cache. The function uses
the portable tsrm_tls_get macro which is cheap
- all the TSRM_* macros are set to placebo. Thus this opens the way
remove them later
Except that, the logic is old. TSRMLS_FETCH will have to be done once
per thread, then tsrm_get_ls_cache() can be used. Things seeming to be
worky are cli, cli server and apache. I also tried to enable bz2
shared and it has worked out of the box. The change is yet minimal
diffing to the current master bus is a worky start, IMHO. Though will
have to recheck the other previously done SAPIs - embed and cgi.
The offsets can be added to the tsrm_resource_type struct, then
it'll not be needed to declare them in the userspace. Even the
"done" member type can be changed to int16 or smaller, then adding
the offset as int16 will not change the struct size. As well on the
todo might be removing the hashed storage, thread_id != thread_id and
linked list logic in favour of the explicit TLS operations.
2014-09-26 00:48:27 +08:00
|
|
|
TSRM_API inline void *tsrm_get_ls_cache(void);
|
|
|
|
|
2014-10-01 01:16:23 +08:00
|
|
|
#ifdef TSRM_WIN32
|
|
|
|
# define TSRM_TLS __declspec(thread)
|
|
|
|
#else
|
|
|
|
# define TSRM_TLS __thread
|
|
|
|
#endif
|
|
|
|
|
reworked the patch, less new stuff but worky
TLS is already used in TSRM, the way exporting the tsrm cache through
a thread local variable is not portable. Additionally, the current
patch suffers from bugs which are hard to find, but prevent it to
be worky with apache. What is done here is mainly uses the idea
from the RFC patch, but
- __thread variable is removed
- offset math and declarations are removed
- extra macros and definitions are removed
What is done merely is
- use an inline function to access the tsrm cache. The function uses
the portable tsrm_tls_get macro which is cheap
- all the TSRM_* macros are set to placebo. Thus this opens the way
remove them later
Except that, the logic is old. TSRMLS_FETCH will have to be done once
per thread, then tsrm_get_ls_cache() can be used. Things seeming to be
worky are cli, cli server and apache. I also tried to enable bz2
shared and it has worked out of the box. The change is yet minimal
diffing to the current master bus is a worky start, IMHO. Though will
have to recheck the other previously done SAPIs - embed and cgi.
The offsets can be added to the tsrm_resource_type struct, then
it'll not be needed to declare them in the userspace. Even the
"done" member type can be changed to int16 or smaller, then adding
the offset as int16 will not change the struct size. As well on the
todo might be removing the hashed storage, thread_id != thread_id and
linked list logic in favour of the explicit TLS operations.
2014-09-26 00:48:27 +08:00
|
|
|
#define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1)
|
|
|
|
#define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1)
|
|
|
|
|
2014-10-01 07:33:01 +08:00
|
|
|
#define TSRMLS_FETCH_FROM_CTX(ctx) void ***tsrm_ls = (void ***) ctx
|
|
|
|
#define TSRMLS_SET_CTX(ctx) ctx = (void ***) tsrm_get_ls_cache()
|
|
|
|
#define TSRMG(id, type, element) (((type) (*((void ***) tsrm_get_ls_cache()))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
|
2014-10-02 04:04:21 +08:00
|
|
|
|
2014-12-16 17:44:43 +08:00
|
|
|
#define TSRMG_STATIC(id, type, element) (((type) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(id)])->element)
|
|
|
|
#define TSRMLS_CACHE_EXTERN extern TSRM_TLS void *TSRMLS_CACHE
|
|
|
|
#define TSRMLS_CACHE_DEFINE TSRM_TLS void *TSRMLS_CACHE = NULL
|
|
|
|
#define TSRMLS_CACHE_UPDATE if (!TSRMLS_CACHE) TSRMLS_CACHE = tsrm_get_ls_cache()
|
2014-10-15 22:33:40 +08:00
|
|
|
#define TSRMLS_CACHE _tsrm_ls_cache
|
2014-10-02 04:04:21 +08:00
|
|
|
|
|
|
|
/* BC only */
|
2014-12-11 17:03:39 +08:00
|
|
|
#define TSRMLS_D void
|
reworked the patch, less new stuff but worky
TLS is already used in TSRM, the way exporting the tsrm cache through
a thread local variable is not portable. Additionally, the current
patch suffers from bugs which are hard to find, but prevent it to
be worky with apache. What is done here is mainly uses the idea
from the RFC patch, but
- __thread variable is removed
- offset math and declarations are removed
- extra macros and definitions are removed
What is done merely is
- use an inline function to access the tsrm cache. The function uses
the portable tsrm_tls_get macro which is cheap
- all the TSRM_* macros are set to placebo. Thus this opens the way
remove them later
Except that, the logic is old. TSRMLS_FETCH will have to be done once
per thread, then tsrm_get_ls_cache() can be used. Things seeming to be
worky are cli, cli server and apache. I also tried to enable bz2
shared and it has worked out of the box. The change is yet minimal
diffing to the current master bus is a worky start, IMHO. Though will
have to recheck the other previously done SAPIs - embed and cgi.
The offsets can be added to the tsrm_resource_type struct, then
it'll not be needed to declare them in the userspace. Even the
"done" member type can be changed to int16 or smaller, then adding
the offset as int16 will not change the struct size. As well on the
todo might be removing the hashed storage, thread_id != thread_id and
linked list logic in favour of the explicit TLS operations.
2014-09-26 00:48:27 +08:00
|
|
|
#define TSRMLS_DC
|
|
|
|
#define TSRMLS_C
|
|
|
|
#define TSRMLS_CC
|
2014-10-15 15:46:35 +08:00
|
|
|
#define TSRMLS_FETCH()
|
2014-09-23 02:58:45 +08:00
|
|
|
|
1999-08-14 17:35:52 +08:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
1999-04-21 07:58:02 +08:00
|
|
|
|
2001-07-28 18:46:11 +08:00
|
|
|
#else /* non ZTS */
|
2001-07-28 08:46:42 +08:00
|
|
|
|
2001-07-28 18:46:11 +08:00
|
|
|
#define TSRMLS_FETCH()
|
2003-06-25 13:05:06 +08:00
|
|
|
#define TSRMLS_FETCH_FROM_CTX(ctx)
|
|
|
|
#define TSRMLS_SET_CTX(ctx)
|
2014-10-02 04:04:21 +08:00
|
|
|
|
|
|
|
#define TSRMG_STATIC(id, type, element)
|
|
|
|
#define TSRMLS_CACHE_EXTERN
|
|
|
|
#define TSRMLS_CACHE_DEFINE
|
|
|
|
#define TSRMLS_CACHE_UPDATE
|
2014-10-15 22:33:40 +08:00
|
|
|
#define TSRMLS_CACHE
|
2014-10-02 04:04:21 +08:00
|
|
|
|
|
|
|
/* BC only */
|
2001-08-03 00:03:17 +08:00
|
|
|
#define TSRMLS_D void
|
2001-07-28 08:46:42 +08:00
|
|
|
#define TSRMLS_DC
|
|
|
|
#define TSRMLS_C
|
|
|
|
#define TSRMLS_CC
|
|
|
|
|
2000-09-01 07:44:10 +08:00
|
|
|
#endif /* ZTS */
|
|
|
|
|
2000-07-03 07:16:54 +08:00
|
|
|
#endif /* TSRM_H */
|