php-src/TSRM/TSRM.h

195 lines
6.0 KiB
C
Raw Normal View History

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 |
| 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
+----------------------------------------------------------------------+
2018-11-02 00:30:28 +08:00
| Authors: Zeev Suraski <zeev@php.net> |
1999-04-23 19:00:02 +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
# include "Zend/zend_config.w32.h"
2007-02-16 03:11:48 +08:00
#else
# include "main/php_config.h"
2001-07-28 20:16:43 +08:00
#endif
2014-12-22 18:28:13 +08:00
#include "main/php_stdint.h"
#ifdef TSRM_WIN32
# ifdef TSRM_EXPORTS
# define TSRM_API __declspec(dllexport)
# else
# define TSRM_API __declspec(dllimport)
# endif
#elif defined(__GNUC__) && __GNUC__ >= 4
# define TSRM_API __attribute__ ((visibility("default")))
#else
# define TSRM_API
#endif
typedef intptr_t tsrm_intptr_t;
typedef uintptr_t tsrm_uintptr_t;
2007-04-16 16:09:56 +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
# ifndef TSRM_INCLUDE_FULL_WINDOWS_HEADERS
# define WIN32_LEAN_AND_MEAN
# endif
2019-03-23 15:15:53 +08:00
#else
1999-04-24 17:01:30 +08:00
# include <pthread.h>
#endif
1999-04-21 07:58:02 +08:00
#if SIZEOF_SIZE_T == 4
# define TSRM_ALIGNED_SIZE(size) \
(((size) + INT32_C(15)) & ~INT32_C(15))
#else
# define TSRM_ALIGNED_SIZE(size) \
(((size) + INT64_C(15)) & ~INT64_C(15))
#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
# define MUTEX_T CRITICAL_SECTION *
2019-03-23 15:15:53 +08:00
#else
1999-04-21 07:58:02 +08:00
# define THREAD_T pthread_t
# define MUTEX_T pthread_mutex_t *
#endif
#include <signal.h>
typedef void (*ts_allocate_ctor)(void *);
typedef void (*ts_allocate_dtor)(void *);
2014-09-26 00:48:27 +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 */
TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debug_level, const char *debug_filename);
TSRM_API void tsrm_shutdown(void);
1999-04-21 07:58:02 +08:00
2019-03-29 15:01:31 +08:00
/* environ lock API */
TSRM_API void tsrm_env_lock(void);
TSRM_API void tsrm_env_unlock(void);
2019-03-29 15:01:31 +08:00
1999-04-21 07:58:02 +08:00
/* allocates a new thread-safe-resource id */
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
/* Fast resource in reserved (pre-allocated) space */
TSRM_API void tsrm_reserve(size_t size);
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);
1999-04-21 07:58:02 +08:00
/* fetches the requested resource for the current thread */
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 */
TSRM_API void ts_free_thread(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 */
#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
typedef void (*tsrm_thread_begin_func_t)(THREAD_T thread_id);
typedef void (*tsrm_thread_end_func_t)(THREAD_T thread_id);
typedef void (*tsrm_shutdown_func_t)(void);
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, const 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);
#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);
TSRM_API void *tsrm_set_shutdown_handler(tsrm_shutdown_func_t shutdown_handler);
1999-08-14 17:35:52 +08:00
2014-12-22 03:01:39 +08:00
TSRM_API void *tsrm_get_ls_cache(void);
2019-04-01 15:27:11 +08:00
TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void);
2017-04-15 20:28:58 +08:00
TSRM_API uint8_t tsrm_is_main_thread(void);
2019-06-26 19:18:50 +08:00
TSRM_API uint8_t tsrm_is_shutdown(void);
2017-12-22 00:54:31 +08:00
TSRM_API const char *tsrm_api_name(void);
2014-09-26 00:48:27 +08:00
#ifdef TSRM_WIN32
# define TSRM_TLS __declspec(thread)
#else
# define TSRM_TLS __thread
#endif
#ifndef __has_attribute
# define __has_attribute(x) 0
#endif
#if !__has_attribute(tls_model)
# define TSRM_TLS_MODEL_ATTR
#elif __PIC__
# define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("initial-exec")))
#else
# define TSRM_TLS_MODEL_ATTR __attribute__((tls_model("local-exec")))
#endif
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)
2015-07-30 14:31:00 +08:00
#define TSRMG(id, type, element) (TSRMG_BULK(id, type)->element)
#define TSRMG_BULK(id, type) ((type) (*((void ***) tsrm_get_ls_cache()))[TSRM_UNSHUFFLE_RSRC_ID(id)])
#define TSRMG_FAST(offset, type, element) (TSRMG_FAST_BULK(offset, type)->element)
#define TSRMG_FAST_BULK(offset, type) ((type) (((char*) tsrm_get_ls_cache())+(offset)))
2015-07-30 14:31:00 +08:00
#define TSRMG_STATIC(id, type, element) (TSRMG_BULK_STATIC(id, type)->element)
#define TSRMG_BULK_STATIC(id, type) ((type) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(id)])
#define TSRMG_FAST_STATIC(offset, type, element) (TSRMG_FAST_BULK_STATIC(offset, type)->element)
#define TSRMG_FAST_BULK_STATIC(offset, type) ((type) (((char*) TSRMLS_CACHE)+(offset)))
#define TSRMLS_CACHE_EXTERN() extern TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR;
#define TSRMLS_CACHE_DEFINE() TSRM_TLS void *TSRMLS_CACHE TSRM_TLS_MODEL_ATTR = NULL;
#define TSRMLS_CACHE_UPDATE() TSRMLS_CACHE = tsrm_get_ls_cache()
#define TSRMLS_CACHE _tsrm_ls_cache
1999-08-14 17:35:52 +08:00
#ifdef __cplusplus
}
#endif
1999-04-21 07:58:02 +08:00
#else /* non ZTS */
2001-07-28 08:46:42 +08:00
#define tsrm_env_lock()
#define tsrm_env_unlock()
2019-03-29 15:01:31 +08:00
#define TSRMG_STATIC(id, type, element)
#define TSRMLS_CACHE_EXTERN()
#define TSRMLS_CACHE_DEFINE()
#define TSRMLS_CACHE_UPDATE()
#define TSRMLS_CACHE
2015-08-17 17:34:33 +08:00
#define TSRM_TLS
#endif /* ZTS */
#endif /* TSRM_H */