From: Wez Furlong Date: Wed, 27 Apr 2005 22:19:54 +0000 (+0000) Subject: Add three new TSRM api functions: X-Git-Tag: php-5.0.1b1~395 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6d978a62f1b69760870524fcf2f3900063d35ced;p=php 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. --- 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; icount; i++) { + if (resource_types_table[i].dtor) { + resource_types_table[i].dtor(thread_resources->storage[i], &thread_resources->storage); + } + } + for (i=0; icount; 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)