diff options
author | Wez Furlong <wez@php.net> | 2005-04-27 22:19:54 +0000 |
---|---|---|
committer | Wez Furlong <wez@php.net> | 2005-04-27 22:19:54 +0000 |
commit | 6d978a62f1b69760870524fcf2f3900063d35ced (patch) | |
tree | 89bed8d6878b1352394177e6fa98d7654e869e0b /TSRM | |
parent | 396acbf64c9b4bcd312fdbad70741493a1b1d9b6 (diff) | |
download | php-git-6d978a62f1b69760870524fcf2f3900063d35ced.tar.gz |
Add three new TSRM api functions:
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);
These can be used, with a suitable SAPI, to host multiple interpreters on
the same thread.
Diffstat (limited to 'TSRM')
-rw-r--r-- | TSRM/TSRM.c | 90 | ||||
-rw-r--r-- | TSRM/TSRM.h | 6 |
2 files changed, 96 insertions, 0 deletions
diff --git a/TSRM/TSRM.c b/TSRM/TSRM.c index 4d7e80edef..786e4081e2 100644 --- a/TSRM/TSRM.c +++ b/TSRM/TSRM.c @@ -379,6 +379,96 @@ TSRM_API void *ts_resource_ex(ts_rsrc_id id, THREAD_T *th_id) #endif } +/* 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) { + resource_types_table[i].dtor(thread_resources->storage[i], &thread_resources->storage); + } + } + for (i=0; i<thread_resources->count; i++) { + free(thread_resources->storage[i]); + } + free(thread_resources->storage); + free(thread_resources); + thread_resources = next; + } +} + +void *tsrm_set_interpreter_context(void *new_ctx) +{ + tsrm_tls_entry *current; + +#if defined(PTHREADS) + current = pthread_getspecific(tls_key); +#elif defined(TSRM_ST) + current = st_thread_getspecific(tls_key); +#elif defined(TSRM_WIN32) + current = TlsGetValue(tls_key); +#elif defined(BETHREADS) + current = (tsrm_tls_entry*)tls_get(tls_key); +#else +#warning tsrm_set_interpreter_context is probably broken on this platform + current = NULL; +#endif + + /* 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 */ +#if defined(PTHREADS) + pthread_setspecific(tls_key, new_ctx); +#elif defined(TSRM_ST) + st_thread_setspecific(tls_key, new_ctx); +#elif defined(TSRM_WIN32) + TlsSetValue(tls_key, new_ctx); +#elif defined(BETHREADS) + tls_set(tls_key, new_ctx); +#endif + + /* 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); + +#if defined(PTHREADS) + current = pthread_getspecific(tls_key); +#elif defined(TSRM_ST) + current = st_thread_getspecific(tls_key); +#elif defined(TSRM_WIN32) + current = TlsGetValue(tls_key); +#elif defined(BETHREADS) + current = (tsrm_tls_entry*)tls_get(tls_key); +#else +#warning tsrm_new_interpreter_context is probably broken on this platform + current = NULL; +#endif + + new_ctx = malloc(sizeof(*new_ctx)); + 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); +} + /* frees all resources allocated for the current thread */ void ts_free_thread(void) diff --git a/TSRM/TSRM.h b/TSRM/TSRM.h index a66353b88f..cbc9cf81c7 100644 --- a/TSRM/TSRM.h +++ b/TSRM/TSRM.h @@ -132,6 +132,12 @@ TSRM_API int tsrm_mutex_unlock(MUTEX_T mutexp); 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); +/* 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); + #define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1) #define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1) |