summaryrefslogtreecommitdiff
path: root/TSRM
diff options
context:
space:
mode:
authorWez Furlong <wez@php.net>2005-04-27 22:19:54 +0000
committerWez Furlong <wez@php.net>2005-04-27 22:19:54 +0000
commit6d978a62f1b69760870524fcf2f3900063d35ced (patch)
tree89bed8d6878b1352394177e6fa98d7654e869e0b /TSRM
parent396acbf64c9b4bcd312fdbad70741493a1b1d9b6 (diff)
downloadphp-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.c90
-rw-r--r--TSRM/TSRM.h6
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)