? TSRM/a.patch
Index: TSRM/TSRM.c
===================================================================
RCS file: /repository/TSRM/TSRM.c,v
retrieving revision 1.64
diff -u -3 -r1.64 TSRM.c
--- TSRM/TSRM.c 20 Mar 2005 09:03:40 -0000 1.64
+++ TSRM/TSRM.c 22 Apr 2005 14:22:53 -0000
@@ -379,6 +379,96 @@
#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)
Index: TSRM/TSRM.h
===================================================================
RCS file: /repository/TSRM/TSRM.h,v
retrieving revision 1.48
diff -u -3 -r1.48 TSRM.h
--- TSRM/TSRM.h 17 Mar 2005 08:15:22 -0000 1.48
+++ TSRM/TSRM.h 22 Apr 2005 14:22:53 -0000
@@ -132,6 +132,12 @@
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)