]> granicus.if.org Git - php/commitdiff
Add three new TSRM api functions:
authorWez Furlong <wez@php.net>
Wed, 27 Apr 2005 22:19:54 +0000 (22:19 +0000)
committerWez Furlong <wez@php.net>
Wed, 27 Apr 2005 22:19:54 +0000 (22:19 +0000)
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.

TSRM/TSRM.c
TSRM/TSRM.h

index 4d7e80edef1b90c834b23223ac122e322260b866..786e4081e2752cfc470cfc1f75eb16f164366588 100644 (file)
@@ -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)
index a66353b88f9a0969c8fb729c5a3a7529bdd98369..cbc9cf81c73de963e6562bd5c6b195a725b87dc5 100644 (file)
@@ -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)