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
|
|
|
+----------------------------------------------------------------------+
|
|
|
|
*/
|
|
|
|
|
1999-04-21 07:58:02 +08:00
|
|
|
#include "TSRM.h"
|
2000-09-01 07:44:10 +08:00
|
|
|
|
|
|
|
#ifdef ZTS
|
|
|
|
|
1999-04-21 07:58:02 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
|
1999-04-24 17:01:30 +08:00
|
|
|
#if HAVE_STDARG_H
|
|
|
|
#include <stdarg.h>
|
|
|
|
#endif
|
|
|
|
|
1999-04-21 07:58:02 +08:00
|
|
|
typedef struct _tsrm_tls_entry tsrm_tls_entry;
|
|
|
|
|
2014-10-15 22:33:40 +08:00
|
|
|
#if defined(TSRM_WIN32)
|
|
|
|
/* TSRMLS_CACHE_DEFINE; is already done in Zend, this is being always compiled statically. */
|
|
|
|
#endif
|
|
|
|
|
1999-04-21 07:58:02 +08:00
|
|
|
struct _tsrm_tls_entry {
|
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
|
|
|
void **storage;
|
1999-04-21 07:58:02 +08:00
|
|
|
int count;
|
|
|
|
THREAD_T thread_id;
|
|
|
|
tsrm_tls_entry *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
size_t size;
|
1999-12-06 00:21:37 +08:00
|
|
|
ts_allocate_ctor ctor;
|
|
|
|
ts_allocate_dtor dtor;
|
2004-05-13 06:28:28 +08:00
|
|
|
int done;
|
1999-04-21 07:58:02 +08:00
|
|
|
} tsrm_resource_type;
|
|
|
|
|
|
|
|
|
|
|
|
/* The memory manager table */
|
2000-11-18 07:31:15 +08:00
|
|
|
static tsrm_tls_entry **tsrm_tls_table=NULL;
|
1999-04-21 07:58:02 +08:00
|
|
|
static int tsrm_tls_table_size;
|
|
|
|
static ts_rsrc_id id_count;
|
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-04-21 07:58:02 +08:00
|
|
|
/* The resource sizes table */
|
2000-11-18 07:31:15 +08:00
|
|
|
static tsrm_resource_type *resource_types_table=NULL;
|
1999-04-21 07:58:02 +08:00
|
|
|
static int resource_types_table_size;
|
|
|
|
|
|
|
|
|
|
|
|
static MUTEX_T tsmm_mutex; /* thread-safe memory manager mutex */
|
|
|
|
|
1999-08-14 17:35:52 +08:00
|
|
|
/* New thread handlers */
|
2001-07-30 09:46:35 +08:00
|
|
|
static tsrm_thread_begin_func_t tsrm_new_thread_begin_handler;
|
|
|
|
static tsrm_thread_end_func_t tsrm_new_thread_end_handler;
|
1999-08-14 17:35:52 +08:00
|
|
|
|
1999-04-21 07:58:02 +08:00
|
|
|
/* Debug support */
|
2000-11-18 10:41:14 +08:00
|
|
|
int tsrm_error(int level, const char *format, ...);
|
2001-03-06 23:07:57 +08:00
|
|
|
|
|
|
|
/* Read a resource from a thread's resource storage */
|
2000-11-18 07:31:15 +08:00
|
|
|
static int tsrm_error_level;
|
2000-11-18 10:41:14 +08:00
|
|
|
static FILE *tsrm_error_file;
|
2001-07-27 18:08:26 +08:00
|
|
|
|
2000-11-18 10:41:14 +08:00
|
|
|
#if TSRM_DEBUG
|
2001-07-27 18:08:26 +08:00
|
|
|
#define TSRM_ERROR(args) tsrm_error args
|
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_SAFE_RETURN_RSRC(array, offset, range) \
|
2001-07-27 18:08:26 +08:00
|
|
|
{ \
|
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
|
|
|
int unshuffled_offset = TSRM_UNSHUFFLE_RSRC_ID(offset); \
|
2001-07-27 18:08:26 +08:00
|
|
|
\
|
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
|
|
|
if (offset==0) { \
|
|
|
|
return &array; \
|
|
|
|
} else if ((unshuffled_offset)>=0 && (unshuffled_offset)<(range)) { \
|
2001-07-27 18:08:26 +08:00
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Successfully fetched resource id %d for thread id %ld - 0x%0.8X", \
|
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
|
|
|
unshuffled_offset, (long) thread_resources->thread_id, array[unshuffled_offset])); \
|
|
|
|
return array[unshuffled_offset]; \
|
2001-07-27 18:08:26 +08:00
|
|
|
} else { \
|
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Resource id %d is out of range (%d..%d)", \
|
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
|
|
|
unshuffled_offset, TSRM_SHUFFLE_RSRC_ID(0), TSRM_SHUFFLE_RSRC_ID(thread_resources->count-1))); \
|
2001-07-27 18:08:26 +08:00
|
|
|
return NULL; \
|
|
|
|
} \
|
|
|
|
}
|
2000-11-18 07:31:15 +08:00
|
|
|
#else
|
2002-11-06 01:34:47 +08:00
|
|
|
#define TSRM_ERROR(args)
|
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_SAFE_RETURN_RSRC(array, offset, range) \
|
|
|
|
if (offset==0) { \
|
|
|
|
return &array; \
|
|
|
|
} else { \
|
|
|
|
return array[TSRM_UNSHUFFLE_RSRC_ID(offset)]; \
|
2001-07-27 19:03:32 +08:00
|
|
|
}
|
2000-11-18 07:31:15 +08:00
|
|
|
#endif
|
1999-04-21 07:58:02 +08:00
|
|
|
|
2001-03-06 23:07:57 +08:00
|
|
|
#if defined(PTHREADS)
|
|
|
|
/* Thread local storage */
|
|
|
|
static pthread_key_t tls_key;
|
2005-04-28 10:55:14 +08:00
|
|
|
# define tsrm_tls_set(what) pthread_setspecific(tls_key, (void*)(what))
|
|
|
|
# define tsrm_tls_get() pthread_getspecific(tls_key)
|
|
|
|
|
2001-06-22 00:54:05 +08:00
|
|
|
#elif defined(TSRM_ST)
|
|
|
|
static int tls_key;
|
2005-04-28 10:55:14 +08:00
|
|
|
# define tsrm_tls_set(what) st_thread_setspecific(tls_key, (void*)(what))
|
|
|
|
# define tsrm_tls_get() st_thread_getspecific(tls_key)
|
|
|
|
|
2001-07-30 13:46:31 +08:00
|
|
|
#elif defined(TSRM_WIN32)
|
|
|
|
static DWORD tls_key;
|
2005-04-28 10:55:14 +08:00
|
|
|
# define tsrm_tls_set(what) TlsSetValue(tls_key, (void*)(what))
|
|
|
|
# define tsrm_tls_get() TlsGetValue(tls_key)
|
|
|
|
|
2002-10-05 19:26:17 +08:00
|
|
|
#elif defined(BETHREADS)
|
|
|
|
static int32 tls_key;
|
2005-05-17 06:46:05 +08:00
|
|
|
# define tsrm_tls_set(what) tls_set(tls_key, (void*)(what))
|
2005-04-28 10:55:14 +08:00
|
|
|
# define tsrm_tls_get() (tsrm_tls_entry*)tls_get(tls_key)
|
|
|
|
|
|
|
|
#else
|
|
|
|
# define tsrm_tls_set(what)
|
|
|
|
# define tsrm_tls_get() NULL
|
|
|
|
# warning tsrm_set_interpreter_context is probably broken on this platform
|
2001-03-06 23:07:57 +08:00
|
|
|
#endif
|
|
|
|
|
1999-04-21 07:58:02 +08:00
|
|
|
/* Startup TSRM (call once for the entire process) */
|
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-04-21 07:58:02 +08:00
|
|
|
{
|
1999-12-06 05:55:43 +08:00
|
|
|
#if defined(GNUPTH)
|
|
|
|
pth_init();
|
2001-03-06 23:07:57 +08:00
|
|
|
#elif defined(PTHREADS)
|
|
|
|
pthread_key_create( &tls_key, 0 );
|
2001-06-22 00:54:05 +08:00
|
|
|
#elif defined(TSRM_ST)
|
|
|
|
st_init();
|
|
|
|
st_key_create(&tls_key, 0);
|
2001-07-30 13:46:31 +08:00
|
|
|
#elif defined(TSRM_WIN32)
|
|
|
|
tls_key = TlsAlloc();
|
2002-10-05 19:26:17 +08:00
|
|
|
#elif defined(BETHREADS)
|
2002-10-05 19:34:02 +08:00
|
|
|
tls_key = tls_allocate();
|
1999-12-06 05:55:43 +08:00
|
|
|
#endif
|
|
|
|
|
2000-11-18 10:41:14 +08:00
|
|
|
tsrm_error_file = stderr;
|
|
|
|
tsrm_error_set(debug_level, debug_filename);
|
1999-04-21 07:58:02 +08:00
|
|
|
tsrm_tls_table_size = expected_threads;
|
2000-11-18 10:41:14 +08:00
|
|
|
|
1999-04-21 07:58:02 +08:00
|
|
|
tsrm_tls_table = (tsrm_tls_entry **) calloc(tsrm_tls_table_size, sizeof(tsrm_tls_entry *));
|
|
|
|
if (!tsrm_tls_table) {
|
2001-07-23 12:16:31 +08:00
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate TLS table"));
|
1999-04-21 07:58:02 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
id_count=0;
|
|
|
|
|
|
|
|
resource_types_table_size = expected_resources;
|
|
|
|
resource_types_table = (tsrm_resource_type *) calloc(resource_types_table_size, sizeof(tsrm_resource_type));
|
|
|
|
if (!resource_types_table) {
|
2001-07-23 12:16:31 +08:00
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate resource types table"));
|
1999-04-21 07:58:02 +08:00
|
|
|
free(tsrm_tls_table);
|
2000-11-18 07:31:15 +08:00
|
|
|
tsrm_tls_table = NULL;
|
1999-04-21 07:58:02 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
tsmm_mutex = tsrm_mutex_alloc();
|
|
|
|
|
1999-08-14 17:35:52 +08:00
|
|
|
tsrm_new_thread_begin_handler = tsrm_new_thread_end_handler = NULL;
|
|
|
|
|
2001-07-23 12:16:31 +08:00
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Started up TSRM, %d expected threads, %d expected resources", expected_threads, expected_resources));
|
1999-04-21 07:58:02 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Shutdown TSRM (call once for the entire process) */
|
1999-12-06 00:21:37 +08:00
|
|
|
TSRM_API void tsrm_shutdown(void)
|
1999-04-21 07:58:02 +08:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (tsrm_tls_table) {
|
|
|
|
for (i=0; i<tsrm_tls_table_size; i++) {
|
|
|
|
tsrm_tls_entry *p = tsrm_tls_table[i], *next_p;
|
|
|
|
|
|
|
|
while (p) {
|
|
|
|
int j;
|
|
|
|
|
|
|
|
next_p = p->next;
|
2003-12-14 17:36:23 +08:00
|
|
|
for (j=0; j<p->count; j++) {
|
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
|
|
|
if (p->storage[j]) {
|
|
|
|
if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) {
|
2014-12-16 15:03:15 +08:00
|
|
|
resource_types_table[j].dtor(p->storage[j]);
|
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
|
|
|
}
|
|
|
|
free(p->storage[j]);
|
2014-09-23 23:14:41 +08:00
|
|
|
}
|
1999-04-21 07:58:02 +08:00
|
|
|
}
|
|
|
|
free(p->storage);
|
|
|
|
free(p);
|
|
|
|
p = next_p;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(tsrm_tls_table);
|
2000-11-18 07:31:15 +08:00
|
|
|
tsrm_tls_table = NULL;
|
1999-04-21 07:58:02 +08:00
|
|
|
}
|
|
|
|
if (resource_types_table) {
|
|
|
|
free(resource_types_table);
|
2000-11-18 07:31:15 +08:00
|
|
|
resource_types_table=NULL;
|
1999-04-21 07:58:02 +08:00
|
|
|
}
|
|
|
|
tsrm_mutex_free(tsmm_mutex);
|
2000-11-18 07:31:15 +08:00
|
|
|
tsmm_mutex = NULL;
|
2001-07-23 12:16:31 +08:00
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Shutdown TSRM"));
|
2000-11-18 10:41:14 +08:00
|
|
|
if (tsrm_error_file!=stderr) {
|
|
|
|
fclose(tsrm_error_file);
|
|
|
|
}
|
1999-12-06 05:55:43 +08:00
|
|
|
#if defined(GNUPTH)
|
|
|
|
pth_kill();
|
2001-03-06 23:07:57 +08:00
|
|
|
#elif defined(PTHREADS)
|
2003-08-06 04:03:54 +08:00
|
|
|
pthread_setspecific(tls_key, 0);
|
2001-07-30 13:46:31 +08:00
|
|
|
pthread_key_delete(tls_key);
|
|
|
|
#elif defined(TSRM_WIN32)
|
|
|
|
TlsFree(tls_key);
|
1999-12-06 05:55:43 +08:00
|
|
|
#endif
|
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
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2001-07-23 12:16:31 +08:00
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new resource id, %d bytes", size));
|
1999-04-21 07:58:02 +08:00
|
|
|
|
|
|
|
tsrm_mutex_lock(tsmm_mutex);
|
|
|
|
|
|
|
|
/* obtain a resource id */
|
2001-07-27 18:08:26 +08:00
|
|
|
*rsrc_id = TSRM_SHUFFLE_RSRC_ID(id_count++);
|
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtained resource id %d", *rsrc_id));
|
1999-04-21 07:58:02 +08:00
|
|
|
|
|
|
|
/* store the new resource type in the resource sizes table */
|
|
|
|
if (resource_types_table_size < id_count) {
|
|
|
|
resource_types_table = (tsrm_resource_type *) realloc(resource_types_table, sizeof(tsrm_resource_type)*id_count);
|
|
|
|
if (!resource_types_table) {
|
2000-11-18 07:31:15 +08:00
|
|
|
tsrm_mutex_unlock(tsmm_mutex);
|
2001-07-23 12:16:31 +08:00
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Unable to allocate storage for resource"));
|
2001-07-27 18:08:26 +08:00
|
|
|
*rsrc_id = 0;
|
2000-11-18 07:31:15 +08:00
|
|
|
return 0;
|
1999-04-21 07:58:02 +08:00
|
|
|
}
|
|
|
|
resource_types_table_size = id_count;
|
|
|
|
}
|
2001-07-27 18:08:26 +08:00
|
|
|
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].size = size;
|
|
|
|
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].ctor = ctor;
|
|
|
|
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].dtor = dtor;
|
2004-05-13 06:28:28 +08:00
|
|
|
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].done = 0;
|
1999-04-21 07:58:02 +08:00
|
|
|
|
|
|
|
/* enlarge the arrays for the already active threads */
|
|
|
|
for (i=0; i<tsrm_tls_table_size; i++) {
|
|
|
|
tsrm_tls_entry *p = tsrm_tls_table[i];
|
|
|
|
|
|
|
|
while (p) {
|
|
|
|
if (p->count < id_count) {
|
|
|
|
int j;
|
|
|
|
|
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
|
|
|
p->storage = (void *) realloc(p->storage, sizeof(void *)*id_count);
|
1999-04-21 07:58:02 +08:00
|
|
|
for (j=p->count; j<id_count; j++) {
|
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
|
|
|
p->storage[j] = (void *) malloc(resource_types_table[j].size);
|
1999-04-23 19:00:02 +08:00
|
|
|
if (resource_types_table[j].ctor) {
|
2014-12-16 15:03:15 +08:00
|
|
|
resource_types_table[j].ctor(p->storage[j]);
|
1999-04-23 19:00:02 +08:00
|
|
|
}
|
1999-04-21 07:58:02 +08:00
|
|
|
}
|
|
|
|
p->count = id_count;
|
|
|
|
}
|
|
|
|
p = p->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tsrm_mutex_unlock(tsmm_mutex);
|
|
|
|
|
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_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully allocated new resource id %d", *rsrc_id));
|
2001-07-27 18:08:26 +08:00
|
|
|
return *rsrc_id;
|
1999-04-21 07:58:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_T thread_id)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2001-07-23 12:16:31 +08:00
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Creating data structures for thread %x", thread_id));
|
1999-04-21 07:58:02 +08:00
|
|
|
(*thread_resources_ptr) = (tsrm_tls_entry *) malloc(sizeof(tsrm_tls_entry));
|
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
|
|
|
(*thread_resources_ptr)->storage = (void **) malloc(sizeof(void *)*id_count);
|
1999-04-21 07:58:02 +08:00
|
|
|
(*thread_resources_ptr)->count = id_count;
|
|
|
|
(*thread_resources_ptr)->thread_id = thread_id;
|
|
|
|
(*thread_resources_ptr)->next = NULL;
|
1999-10-10 21:30:03 +08:00
|
|
|
|
2001-04-05 00:33:06 +08:00
|
|
|
/* Set thread local storage to this new thread resources structure */
|
2005-04-28 10:55:14 +08:00
|
|
|
tsrm_tls_set(*thread_resources_ptr);
|
1999-10-10 21:30:03 +08:00
|
|
|
|
|
|
|
if (tsrm_new_thread_begin_handler) {
|
2014-12-12 15:11:14 +08:00
|
|
|
tsrm_new_thread_begin_handler(thread_id);
|
1999-10-10 21:30:03 +08:00
|
|
|
}
|
1999-04-21 07:58:02 +08:00
|
|
|
for (i=0; i<id_count; i++) {
|
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
|
|
|
if (resource_types_table[i].done) {
|
|
|
|
(*thread_resources_ptr)->storage[i] = NULL;
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
(*thread_resources_ptr)->storage[i] = (void *) malloc(resource_types_table[i].size);
|
2004-05-13 14:53:21 +08:00
|
|
|
if (resource_types_table[i].ctor) {
|
2014-12-16 15:03:15 +08:00
|
|
|
resource_types_table[i].ctor((*thread_resources_ptr)->storage[i]);
|
2004-05-13 14:53:21 +08:00
|
|
|
}
|
1999-04-23 19:00:02 +08:00
|
|
|
}
|
1999-04-21 07:58:02 +08:00
|
|
|
}
|
2001-03-06 23:07:57 +08:00
|
|
|
|
1999-08-14 17:35:52 +08:00
|
|
|
if (tsrm_new_thread_end_handler) {
|
2014-12-12 15:11:14 +08:00
|
|
|
tsrm_new_thread_end_handler(thread_id);
|
1999-08-14 17:35:52 +08:00
|
|
|
}
|
2005-03-20 17:03:40 +08:00
|
|
|
|
|
|
|
tsrm_mutex_unlock(tsmm_mutex);
|
1999-04-21 07:58:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* fetches the requested resource for the current thread */
|
2000-06-17 22:56:19 +08:00
|
|
|
TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id)
|
1999-04-21 07:58:02 +08:00
|
|
|
{
|
2000-06-16 22:38:05 +08:00
|
|
|
THREAD_T thread_id;
|
1999-04-21 07:58:02 +08:00
|
|
|
int hash_value;
|
|
|
|
tsrm_tls_entry *thread_resources;
|
|
|
|
|
2003-06-25 13:05:06 +08:00
|
|
|
#ifdef NETWARE
|
|
|
|
/* The below if loop is added for NetWare to fix an abend while unloading PHP
|
|
|
|
* when an Apache unload command is issued on the system console.
|
|
|
|
* While exiting from PHP, at the end for some reason, this function is called
|
|
|
|
* with tsrm_tls_table = NULL. When this happened, the server abends when
|
|
|
|
* tsrm_tls_table is accessed since it is NULL.
|
|
|
|
*/
|
|
|
|
if(tsrm_tls_table) {
|
|
|
|
#endif
|
2001-04-28 02:50:35 +08:00
|
|
|
if (!th_id) {
|
2001-04-05 00:33:06 +08:00
|
|
|
/* Fast path for looking up the resources for the current
|
2001-07-27 18:08:26 +08:00
|
|
|
* thread. Its used by just about every call to
|
|
|
|
* ts_resource_ex(). This avoids the need for a mutex lock
|
|
|
|
* and our hashtable lookup.
|
|
|
|
*/
|
2005-04-28 10:55:14 +08:00
|
|
|
thread_resources = tsrm_tls_get();
|
|
|
|
|
2001-04-28 02:50:35 +08:00
|
|
|
if (thread_resources) {
|
2001-07-27 18:08:26 +08:00
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for current thread %d", id, (long) thread_resources->thread_id));
|
|
|
|
/* Read a specific resource from the thread's resources.
|
|
|
|
* This is called outside of a mutex, so have to be aware about external
|
|
|
|
* changes to the structure as we read it.
|
|
|
|
*/
|
|
|
|
TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
|
2001-04-05 00:33:06 +08:00
|
|
|
}
|
2000-06-16 22:38:05 +08:00
|
|
|
thread_id = tsrm_thread_id();
|
2001-03-06 23:07:57 +08:00
|
|
|
} else {
|
|
|
|
thread_id = *th_id;
|
2001-04-05 00:33:06 +08:00
|
|
|
}
|
2001-03-06 23:07:57 +08:00
|
|
|
|
2001-07-23 12:16:31 +08:00
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for thread %ld", id, (long) thread_id));
|
1999-04-21 07:58:02 +08:00
|
|
|
tsrm_mutex_lock(tsmm_mutex);
|
|
|
|
|
|
|
|
hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size);
|
|
|
|
thread_resources = tsrm_tls_table[hash_value];
|
|
|
|
|
|
|
|
if (!thread_resources) {
|
|
|
|
allocate_new_resource(&tsrm_tls_table[hash_value], thread_id);
|
2001-03-01 09:06:36 +08:00
|
|
|
return ts_resource_ex(id, &thread_id);
|
1999-04-21 07:58:02 +08:00
|
|
|
} else {
|
|
|
|
do {
|
|
|
|
if (thread_resources->thread_id == thread_id) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (thread_resources->next) {
|
|
|
|
thread_resources = thread_resources->next;
|
|
|
|
} else {
|
|
|
|
allocate_new_resource(&thread_resources->next, thread_id);
|
2001-03-01 09:06:36 +08:00
|
|
|
return ts_resource_ex(id, &thread_id);
|
1999-10-10 21:30:03 +08:00
|
|
|
/*
|
|
|
|
* thread_resources = thread_resources->next;
|
|
|
|
* break;
|
|
|
|
*/
|
1999-04-21 07:58:02 +08:00
|
|
|
}
|
|
|
|
} while (thread_resources);
|
|
|
|
}
|
2001-03-06 23:07:57 +08:00
|
|
|
tsrm_mutex_unlock(tsmm_mutex);
|
2001-07-27 18:08:26 +08:00
|
|
|
/* Read a specific resource from the thread's resources.
|
|
|
|
* This is called outside of a mutex, so have to be aware about external
|
|
|
|
* changes to the structure as we read it.
|
|
|
|
*/
|
|
|
|
TSRM_SAFE_RETURN_RSRC(thread_resources->storage, id, thread_resources->count);
|
2003-06-25 13:05:06 +08:00
|
|
|
#ifdef NETWARE
|
|
|
|
} /* if(tsrm_tls_table) */
|
|
|
|
#endif
|
1999-04-21 07:58:02 +08:00
|
|
|
}
|
|
|
|
|
2005-04-28 06:19:54 +08:00
|
|
|
/* frees an interpreter context. You are responsible for making sure that
|
|
|
|
* it is not linked into the TSRM hash, and not marked as the current interpreter */
|
|
|
|
void tsrm_free_interpreter_context(void *context)
|
|
|
|
{
|
|
|
|
tsrm_tls_entry *next, *thread_resources = (tsrm_tls_entry*)context;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
while (thread_resources) {
|
|
|
|
next = thread_resources->next;
|
|
|
|
|
|
|
|
for (i=0; i<thread_resources->count; i++) {
|
|
|
|
if (resource_types_table[i].dtor) {
|
2014-12-16 15:03:15 +08:00
|
|
|
resource_types_table[i].dtor(thread_resources->storage[i]);
|
2005-04-28 06:19:54 +08:00
|
|
|
}
|
|
|
|
}
|
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
|
|
|
for (i=0; i<thread_resources->count; i++) {
|
|
|
|
free(thread_resources->storage[i]);
|
|
|
|
}
|
2005-04-28 06:19:54 +08:00
|
|
|
free(thread_resources->storage);
|
|
|
|
free(thread_resources);
|
|
|
|
thread_resources = next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void *tsrm_set_interpreter_context(void *new_ctx)
|
|
|
|
{
|
|
|
|
tsrm_tls_entry *current;
|
|
|
|
|
2005-04-28 10:55:14 +08:00
|
|
|
current = tsrm_tls_get();
|
2005-04-28 06:19:54 +08:00
|
|
|
|
|
|
|
/* TODO: unlink current from the global linked list, and replace it
|
|
|
|
* it with the new context, protected by mutex where/if appropriate */
|
|
|
|
|
|
|
|
/* Set thread local storage to this new thread resources structure */
|
2005-04-28 10:55:14 +08:00
|
|
|
tsrm_tls_set(new_ctx);
|
2005-04-28 06:19:54 +08:00
|
|
|
|
|
|
|
/* return old context, so caller can restore it when they're done */
|
|
|
|
return current;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* allocates a new interpreter context */
|
|
|
|
void *tsrm_new_interpreter_context(void)
|
|
|
|
{
|
|
|
|
tsrm_tls_entry *new_ctx, *current;
|
|
|
|
THREAD_T thread_id;
|
|
|
|
|
|
|
|
thread_id = tsrm_thread_id();
|
|
|
|
tsrm_mutex_lock(tsmm_mutex);
|
|
|
|
|
2005-04-28 10:55:14 +08:00
|
|
|
current = tsrm_tls_get();
|
2005-04-28 06:19:54 +08:00
|
|
|
|
|
|
|
allocate_new_resource(&new_ctx, thread_id);
|
|
|
|
|
|
|
|
/* switch back to the context that was in use prior to our creation
|
|
|
|
* of the new one */
|
|
|
|
return tsrm_set_interpreter_context(current);
|
|
|
|
}
|
|
|
|
|
1999-04-21 07:58:02 +08:00
|
|
|
|
|
|
|
/* frees all resources allocated for the current thread */
|
1999-12-06 00:21:37 +08:00
|
|
|
void ts_free_thread(void)
|
1999-04-21 07:58:02 +08:00
|
|
|
{
|
2001-03-06 23:07:57 +08:00
|
|
|
tsrm_tls_entry *thread_resources;
|
2001-04-05 00:33:06 +08:00
|
|
|
int i;
|
1999-04-21 07:58:02 +08:00
|
|
|
THREAD_T thread_id = tsrm_thread_id();
|
|
|
|
int hash_value;
|
|
|
|
tsrm_tls_entry *last=NULL;
|
|
|
|
|
|
|
|
tsrm_mutex_lock(tsmm_mutex);
|
|
|
|
hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size);
|
|
|
|
thread_resources = tsrm_tls_table[hash_value];
|
|
|
|
|
|
|
|
while (thread_resources) {
|
|
|
|
if (thread_resources->thread_id == thread_id) {
|
|
|
|
for (i=0; i<thread_resources->count; i++) {
|
1999-04-23 19:00:02 +08:00
|
|
|
if (resource_types_table[i].dtor) {
|
2014-12-16 15:03:15 +08:00
|
|
|
resource_types_table[i].dtor(thread_resources->storage[i]);
|
2001-04-05 00:33:06 +08:00
|
|
|
}
|
|
|
|
}
|
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
|
|
|
for (i=0; i<thread_resources->count; i++) {
|
|
|
|
free(thread_resources->storage[i]);
|
|
|
|
}
|
1999-04-21 07:58:02 +08:00
|
|
|
free(thread_resources->storage);
|
2001-04-05 05:43:04 +08:00
|
|
|
if (last) {
|
|
|
|
last->next = thread_resources->next;
|
|
|
|
} else {
|
|
|
|
tsrm_tls_table[hash_value] = thread_resources->next;
|
|
|
|
}
|
2005-04-28 10:55:14 +08:00
|
|
|
tsrm_tls_set(0);
|
1999-04-21 07:58:02 +08:00
|
|
|
free(thread_resources);
|
2001-04-05 05:43:04 +08:00
|
|
|
break;
|
1999-04-21 07:58:02 +08:00
|
|
|
}
|
|
|
|
if (thread_resources->next) {
|
|
|
|
last = thread_resources;
|
|
|
|
}
|
1999-05-12 05:27:44 +08:00
|
|
|
thread_resources = thread_resources->next;
|
1999-04-21 07:58:02 +08:00
|
|
|
}
|
|
|
|
tsrm_mutex_unlock(tsmm_mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-03-14 23:16:07 +08:00
|
|
|
/* frees all resources allocated for all threads except current */
|
|
|
|
void ts_free_worker_threads(void)
|
|
|
|
{
|
|
|
|
tsrm_tls_entry *thread_resources;
|
|
|
|
int i;
|
|
|
|
THREAD_T thread_id = tsrm_thread_id();
|
|
|
|
int hash_value;
|
|
|
|
tsrm_tls_entry *last=NULL;
|
|
|
|
|
|
|
|
tsrm_mutex_lock(tsmm_mutex);
|
|
|
|
hash_value = THREAD_HASH_OF(thread_id, tsrm_tls_table_size);
|
|
|
|
thread_resources = tsrm_tls_table[hash_value];
|
|
|
|
|
|
|
|
while (thread_resources) {
|
|
|
|
if (thread_resources->thread_id != thread_id) {
|
|
|
|
for (i=0; i<thread_resources->count; i++) {
|
|
|
|
if (resource_types_table[i].dtor) {
|
2014-12-16 15:03:15 +08:00
|
|
|
resource_types_table[i].dtor(thread_resources->storage[i]);
|
2006-03-14 23:16:07 +08:00
|
|
|
}
|
|
|
|
}
|
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
|
|
|
for (i=0; i<thread_resources->count; i++) {
|
|
|
|
free(thread_resources->storage[i]);
|
|
|
|
}
|
2006-03-14 23:16:07 +08:00
|
|
|
free(thread_resources->storage);
|
|
|
|
if (last) {
|
|
|
|
last->next = thread_resources->next;
|
|
|
|
} else {
|
|
|
|
tsrm_tls_table[hash_value] = thread_resources->next;
|
|
|
|
}
|
|
|
|
free(thread_resources);
|
|
|
|
if (last) {
|
|
|
|
thread_resources = last->next;
|
|
|
|
} else {
|
|
|
|
thread_resources = tsrm_tls_table[hash_value];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (thread_resources->next) {
|
|
|
|
last = thread_resources;
|
|
|
|
}
|
|
|
|
thread_resources = thread_resources->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tsrm_mutex_unlock(tsmm_mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-04-21 07:58:02 +08:00
|
|
|
/* deallocates all occurrences of a given id */
|
|
|
|
void ts_free_id(ts_rsrc_id id)
|
|
|
|
{
|
2004-05-12 18:30:46 +08:00
|
|
|
int i;
|
|
|
|
int j = TSRM_UNSHUFFLE_RSRC_ID(id);
|
|
|
|
|
|
|
|
tsrm_mutex_lock(tsmm_mutex);
|
|
|
|
|
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Freeing resource id %d", id));
|
|
|
|
|
|
|
|
if (tsrm_tls_table) {
|
|
|
|
for (i=0; i<tsrm_tls_table_size; i++) {
|
2004-05-13 06:28:28 +08:00
|
|
|
tsrm_tls_entry *p = tsrm_tls_table[i];
|
2004-05-12 18:30:46 +08:00
|
|
|
|
|
|
|
while (p) {
|
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
|
|
|
if (p->count > j && p->storage[j]) {
|
2004-05-12 18:30:46 +08:00
|
|
|
if (resource_types_table && resource_types_table[j].dtor) {
|
2014-12-16 15:03:15 +08:00
|
|
|
resource_types_table[j].dtor(p->storage[j]);
|
2004-05-12 18:30:46 +08:00
|
|
|
}
|
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
|
|
|
free(p->storage[j]);
|
|
|
|
p->storage[j] = NULL;
|
2004-05-12 18:30:46 +08:00
|
|
|
}
|
|
|
|
p = p->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-05-13 06:28:28 +08:00
|
|
|
resource_types_table[j].done = 1;
|
2004-05-12 18:30:46 +08:00
|
|
|
|
|
|
|
tsrm_mutex_unlock(tsmm_mutex);
|
|
|
|
|
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Successfully freed resource id %d", id));
|
1999-04-21 07:58:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Utility Functions
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Obtain the current thread id */
|
1999-08-14 17:35:52 +08:00
|
|
|
TSRM_API THREAD_T tsrm_thread_id(void)
|
1999-04-21 07:58:02 +08:00
|
|
|
{
|
2000-09-02 23:03:19 +08:00
|
|
|
#ifdef TSRM_WIN32
|
1999-04-21 07:58:02 +08:00
|
|
|
return GetCurrentThreadId();
|
1999-12-06 05:55:43 +08:00
|
|
|
#elif defined(GNUPTH)
|
|
|
|
return pth_self();
|
1999-04-21 07:58:02 +08:00
|
|
|
#elif defined(PTHREADS)
|
|
|
|
return pthread_self();
|
|
|
|
#elif defined(NSAPI)
|
|
|
|
return systhread_current();
|
|
|
|
#elif defined(PI3WEB)
|
|
|
|
return PIThread_getCurrent();
|
2001-06-22 00:54:05 +08:00
|
|
|
#elif defined(TSRM_ST)
|
|
|
|
return st_thread_self();
|
2002-10-05 19:26:17 +08:00
|
|
|
#elif defined(BETHREADS)
|
|
|
|
return find_thread(NULL);
|
1999-04-21 07:58:02 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Allocate a mutex */
|
2000-11-18 07:31:15 +08:00
|
|
|
TSRM_API MUTEX_T tsrm_mutex_alloc(void)
|
1999-04-21 07:58:02 +08:00
|
|
|
{
|
2002-10-05 19:34:02 +08:00
|
|
|
MUTEX_T mutexp;
|
2000-09-02 23:03:19 +08:00
|
|
|
#ifdef TSRM_WIN32
|
2002-10-05 19:34:02 +08:00
|
|
|
mutexp = malloc(sizeof(CRITICAL_SECTION));
|
1999-12-21 04:02:25 +08:00
|
|
|
InitializeCriticalSection(mutexp);
|
1999-12-06 05:55:43 +08:00
|
|
|
#elif defined(GNUPTH)
|
|
|
|
mutexp = (MUTEX_T) malloc(sizeof(*mutexp));
|
|
|
|
pth_mutex_init(mutexp);
|
1999-04-21 07:58:02 +08:00
|
|
|
#elif defined(PTHREADS)
|
|
|
|
mutexp = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
|
|
|
pthread_mutex_init(mutexp,NULL);
|
|
|
|
#elif defined(NSAPI)
|
|
|
|
mutexp = crit_init();
|
|
|
|
#elif defined(PI3WEB)
|
|
|
|
mutexp = PIPlatform_allocLocalMutex();
|
2001-06-22 00:54:05 +08:00
|
|
|
#elif defined(TSRM_ST)
|
|
|
|
mutexp = st_mutex_new();
|
2002-10-05 19:26:17 +08:00
|
|
|
#elif defined(BETHREADS)
|
|
|
|
mutexp = (beos_ben*)malloc(sizeof(beos_ben));
|
|
|
|
mutexp->ben = 0;
|
|
|
|
mutexp->sem = create_sem(1, "PHP sempahore");
|
1999-04-21 07:58:02 +08:00
|
|
|
#endif
|
|
|
|
#ifdef THR_DEBUG
|
2002-10-05 19:34:02 +08:00
|
|
|
printf("Mutex created thread: %d\n",mythreadid());
|
1999-04-21 07:58:02 +08:00
|
|
|
#endif
|
2002-10-05 19:34:02 +08:00
|
|
|
return( mutexp );
|
1999-04-21 07:58:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Free a mutex */
|
2000-11-18 07:31:15 +08:00
|
|
|
TSRM_API void tsrm_mutex_free(MUTEX_T mutexp)
|
1999-04-21 07:58:02 +08:00
|
|
|
{
|
2002-10-05 19:34:02 +08:00
|
|
|
if (mutexp) {
|
2000-09-02 23:03:19 +08:00
|
|
|
#ifdef TSRM_WIN32
|
1999-12-21 04:02:25 +08:00
|
|
|
DeleteCriticalSection(mutexp);
|
2003-06-25 13:05:06 +08:00
|
|
|
free(mutexp);
|
1999-12-06 05:55:43 +08:00
|
|
|
#elif defined(GNUPTH)
|
|
|
|
free(mutexp);
|
1999-04-21 07:58:02 +08:00
|
|
|
#elif defined(PTHREADS)
|
1999-11-26 23:33:42 +08:00
|
|
|
pthread_mutex_destroy(mutexp);
|
1999-12-06 05:55:43 +08:00
|
|
|
free(mutexp);
|
1999-04-21 07:58:02 +08:00
|
|
|
#elif defined(NSAPI)
|
|
|
|
crit_terminate(mutexp);
|
|
|
|
#elif defined(PI3WEB)
|
2001-06-22 00:54:05 +08:00
|
|
|
PISync_delete(mutexp);
|
|
|
|
#elif defined(TSRM_ST)
|
|
|
|
st_mutex_destroy(mutexp);
|
2002-10-05 19:26:17 +08:00
|
|
|
#elif defined(BETHREADS)
|
|
|
|
delete_sem(mutexp->sem);
|
|
|
|
free(mutexp);
|
1999-04-21 07:58:02 +08:00
|
|
|
#endif
|
2002-10-05 19:34:02 +08:00
|
|
|
}
|
1999-04-21 07:58:02 +08:00
|
|
|
#ifdef THR_DEBUG
|
2002-10-05 19:34:02 +08:00
|
|
|
printf("Mutex freed thread: %d\n",mythreadid());
|
1999-04-21 07:58:02 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-07 17:06:45 +08:00
|
|
|
/*
|
|
|
|
Lock a mutex.
|
|
|
|
A return value of 0 indicates success
|
|
|
|
*/
|
2000-11-18 07:31:15 +08:00
|
|
|
TSRM_API int tsrm_mutex_lock(MUTEX_T mutexp)
|
1999-04-21 07:58:02 +08:00
|
|
|
{
|
2001-07-23 12:16:31 +08:00
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Mutex locked thread: %ld", tsrm_thread_id()));
|
2000-09-02 23:03:19 +08:00
|
|
|
#ifdef TSRM_WIN32
|
1999-12-21 04:02:25 +08:00
|
|
|
EnterCriticalSection(mutexp);
|
2008-02-07 17:06:45 +08:00
|
|
|
return 0;
|
1999-12-06 05:55:43 +08:00
|
|
|
#elif defined(GNUPTH)
|
2008-02-07 17:06:45 +08:00
|
|
|
if (pth_mutex_acquire(mutexp, 0, NULL)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return -1;
|
1999-04-21 07:58:02 +08:00
|
|
|
#elif defined(PTHREADS)
|
|
|
|
return pthread_mutex_lock(mutexp);
|
|
|
|
#elif defined(NSAPI)
|
2008-02-07 17:06:45 +08:00
|
|
|
crit_enter(mutexp);
|
|
|
|
return 0;
|
1999-04-21 07:58:02 +08:00
|
|
|
#elif defined(PI3WEB)
|
|
|
|
return PISync_lock(mutexp);
|
2001-06-22 00:54:05 +08:00
|
|
|
#elif defined(TSRM_ST)
|
|
|
|
return st_mutex_lock(mutexp);
|
2002-10-05 19:26:17 +08:00
|
|
|
#elif defined(BETHREADS)
|
|
|
|
if (atomic_add(&mutexp->ben, 1) != 0)
|
2002-10-05 19:34:02 +08:00
|
|
|
return acquire_sem(mutexp->sem);
|
|
|
|
return 0;
|
1999-04-21 07:58:02 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-07 17:06:45 +08:00
|
|
|
/*
|
|
|
|
Unlock a mutex.
|
|
|
|
A return value of 0 indicates success
|
|
|
|
*/
|
2000-11-18 07:31:15 +08:00
|
|
|
TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp)
|
1999-04-21 07:58:02 +08:00
|
|
|
{
|
2001-07-23 12:16:31 +08:00
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Mutex unlocked thread: %ld", tsrm_thread_id()));
|
2000-09-02 23:03:19 +08:00
|
|
|
#ifdef TSRM_WIN32
|
1999-12-21 04:02:25 +08:00
|
|
|
LeaveCriticalSection(mutexp);
|
2008-02-07 17:06:45 +08:00
|
|
|
return 0;
|
1999-12-06 05:55:43 +08:00
|
|
|
#elif defined(GNUPTH)
|
2008-02-07 17:06:45 +08:00
|
|
|
if (pth_mutex_release(mutexp)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return -1;
|
1999-04-21 07:58:02 +08:00
|
|
|
#elif defined(PTHREADS)
|
|
|
|
return pthread_mutex_unlock(mutexp);
|
|
|
|
#elif defined(NSAPI)
|
2008-02-07 17:06:45 +08:00
|
|
|
crit_exit(mutexp);
|
|
|
|
return 0;
|
1999-04-21 07:58:02 +08:00
|
|
|
#elif defined(PI3WEB)
|
|
|
|
return PISync_unlock(mutexp);
|
2001-06-22 00:54:05 +08:00
|
|
|
#elif defined(TSRM_ST)
|
|
|
|
return st_mutex_unlock(mutexp);
|
2002-10-05 19:26:17 +08:00
|
|
|
#elif defined(BETHREADS)
|
2002-10-05 19:34:02 +08:00
|
|
|
if (atomic_add(&mutexp->ben, -1) != 1)
|
|
|
|
return release_sem(mutexp->sem);
|
2002-10-05 19:26:17 +08:00
|
|
|
return 0;
|
1999-04-21 07:58:02 +08:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-06-03 05:16:50 +08:00
|
|
|
/*
|
|
|
|
Changes the signal mask of the calling thread
|
|
|
|
*/
|
|
|
|
#ifdef HAVE_SIGPROCMASK
|
|
|
|
TSRM_API int tsrm_sigmask(int how, const sigset_t *set, sigset_t *oldset)
|
|
|
|
{
|
|
|
|
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Changed sigmask in thread: %ld", tsrm_thread_id()));
|
|
|
|
/* TODO: add support for other APIs */
|
|
|
|
#ifdef PTHREADS
|
|
|
|
return pthread_sigmask(how, set, oldset);
|
|
|
|
#else
|
|
|
|
return sigprocmask(how, set, oldset);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1999-04-21 07:58:02 +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)
|
1999-08-14 17:35:52 +08:00
|
|
|
{
|
|
|
|
void *retval = (void *) tsrm_new_thread_begin_handler;
|
|
|
|
|
|
|
|
tsrm_new_thread_begin_handler = new_thread_begin_handler;
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-07-30 09:46:35 +08:00
|
|
|
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
|
|
|
{
|
|
|
|
void *retval = (void *) tsrm_new_thread_end_handler;
|
|
|
|
|
|
|
|
tsrm_new_thread_end_handler = new_thread_end_handler;
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
1999-04-21 07:58:02 +08:00
|
|
|
/*
|
|
|
|
* Debug support
|
|
|
|
*/
|
|
|
|
|
2000-11-18 10:41:14 +08:00
|
|
|
#if TSRM_DEBUG
|
|
|
|
int tsrm_error(int level, const char *format, ...)
|
1999-04-21 07:58:02 +08:00
|
|
|
{
|
2000-11-18 07:31:15 +08:00
|
|
|
if (level<=tsrm_error_level) {
|
1999-04-21 07:58:02 +08:00
|
|
|
va_list args;
|
|
|
|
int size;
|
|
|
|
|
2000-11-18 10:41:14 +08:00
|
|
|
fprintf(tsrm_error_file, "TSRM: ");
|
1999-04-21 07:58:02 +08:00
|
|
|
va_start(args, format);
|
2000-11-18 10:41:14 +08:00
|
|
|
size = vfprintf(tsrm_error_file, format, args);
|
1999-04-21 07:58:02 +08:00
|
|
|
va_end(args);
|
2000-11-18 10:41:14 +08:00
|
|
|
fprintf(tsrm_error_file, "\n");
|
|
|
|
fflush(tsrm_error_file);
|
1999-04-21 07:58:02 +08:00
|
|
|
return size;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2000-11-18 10:41:14 +08:00
|
|
|
#endif
|
1999-04-21 07:58:02 +08:00
|
|
|
|
|
|
|
|
2000-11-18 10:41:14 +08:00
|
|
|
void tsrm_error_set(int level, char *debug_filename)
|
1999-04-21 07:58:02 +08:00
|
|
|
{
|
2000-11-18 07:31:15 +08:00
|
|
|
tsrm_error_level = level;
|
2000-11-18 10:41:14 +08:00
|
|
|
|
|
|
|
#if TSRM_DEBUG
|
|
|
|
if (tsrm_error_file!=stderr) { /* close files opened earlier */
|
|
|
|
fclose(tsrm_error_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (debug_filename) {
|
|
|
|
tsrm_error_file = fopen(debug_filename, "w");
|
|
|
|
if (!tsrm_error_file) {
|
|
|
|
tsrm_error_file = stderr;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
tsrm_error_file = stderr;
|
|
|
|
}
|
|
|
|
#endif
|
1999-04-24 17:01:30 +08:00
|
|
|
}
|
2000-09-01 07:44:10 +08:00
|
|
|
|
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-09-23 02:58:45 +08:00
|
|
|
{
|
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
|
|
|
return tsrm_tls_get();
|
2014-09-23 02:58:45 +08:00
|
|
|
}
|
|
|
|
|
2000-09-01 07:44:10 +08:00
|
|
|
#endif /* ZTS */
|