The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
? 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)