Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

180 lines (172 sloc) 5.824 kb
Index: TSRM/TSRM.c
===================================================================
RCS file: /repository/TSRM/TSRM.c,v
retrieving revision 1.61.2.3
diff -u -r1.61.2.3 TSRM.c
--- TSRM/TSRM.c 16 Jul 2005 11:50:59 -0000 1.61.2.3
+++ TSRM/TSRM.c 30 Aug 2005 17:33:51 -0000
@@ -94,12 +94,28 @@
#if defined(PTHREADS)
/* Thread local storage */
static pthread_key_t tls_key;
+# define tsrm_tls_set(what) pthread_setspecific(tls_key, (void*)(what))
+# define tsrm_tls_get() pthread_getspecific(tls_key)
+
#elif defined(TSRM_ST)
static int tls_key;
+# define tsrm_tls_set(what) st_thread_setspecific(tls_key, (void*)(what))
+# define tsrm_tls_get() st_thread_getspecific(tls_key)
+
#elif defined(TSRM_WIN32)
static DWORD tls_key;
+# define tsrm_tls_set(what) TlsSetValue(tls_key, (void*)(what))
+# define tsrm_tls_get() TlsGetValue(tls_key)
+
#elif defined(BETHREADS)
static int32 tls_key;
+# define tsrm_tls_set(what) tls_set(tls_key, (void*)(what))
+# define tsrm_tls_get() (tsrm_tls_entry*)tls_get(tls_key)
+
+#else
+# define tsrm_tls_set(what)
+# define tsrm_tls_get() NULL
+# warning tsrm_set_interpreter_context is probably broken on this platform
#endif
/* Startup TSRM (call once for the entire process) */
@@ -268,16 +284,8 @@
(*thread_resources_ptr)->thread_id = thread_id;
(*thread_resources_ptr)->next = NULL;
-#if defined(PTHREADS)
/* Set thread local storage to this new thread resources structure */
- pthread_setspecific(tls_key, (void *) *thread_resources_ptr);
-#elif defined(TSRM_ST)
- st_thread_setspecific(tls_key, (void *) *thread_resources_ptr);
-#elif defined(TSRM_WIN32)
- TlsSetValue(tls_key, (void *) *thread_resources_ptr);
-#elif defined(BETHREADS)
- tls_set(tls_key, (void*) *thread_resources_ptr);
-#endif
+ tsrm_tls_set(*thread_resources_ptr);
if (tsrm_new_thread_begin_handler) {
tsrm_new_thread_begin_handler(thread_id, &((*thread_resources_ptr)->storage));
@@ -321,22 +329,13 @@
if(tsrm_tls_table) {
#endif
if (!th_id) {
-#if defined(PTHREADS)
/* Fast path for looking up the resources for the current
* thread. Its used by just about every call to
* ts_resource_ex(). This avoids the need for a mutex lock
* and our hashtable lookup.
*/
- thread_resources = pthread_getspecific(tls_key);
-#elif defined(TSRM_ST)
- thread_resources = st_thread_getspecific(tls_key);
-#elif defined(TSRM_WIN32)
- thread_resources = TlsGetValue(tls_key);
-#elif defined(BETHREADS)
- thread_resources = (tsrm_tls_entry*)tls_get(tls_key);
-#else
- thread_resources = NULL;
-#endif
+ thread_resources = tsrm_tls_get();
+
if (thread_resources) {
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Fetching resource id %d for current thread %d", id, (long) thread_resources->thread_id));
/* Read a specific resource from the thread's resources.
@@ -387,6 +386,65 @@
#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;
+
+ current = tsrm_tls_get();
+
+ /* 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 */
+ tsrm_tls_set(new_ctx);
+
+ /* 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);
+
+ current = tsrm_tls_get();
+
+ 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)
@@ -417,11 +475,7 @@
} else {
tsrm_tls_table[hash_value] = thread_resources->next;
}
-#if defined(PTHREADS)
- pthread_setspecific(tls_key, 0);
-#elif defined(TSRM_WIN32)
- TlsSetValue(tls_key, 0);
-#endif
+ tsrm_tls_set(0);
free(thread_resources);
break;
}
Index: TSRM/TSRM.h
===================================================================
RCS file: /repository/TSRM/TSRM.h,v
retrieving revision 1.43.2.3
diff -u -r1.43.2.3 TSRM.h
--- TSRM/TSRM.h 11 Mar 2005 11:12:07 -0000 1.43.2.3
+++ TSRM/TSRM.h 30 Aug 2005 17:33:51 -0000
@@ -132,6 +132,13 @@
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_INTERPRETER_PATCH_APPLIED
+
#define TSRM_SHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)+1)
#define TSRM_UNSHUFFLE_RSRC_ID(rsrc_id) ((rsrc_id)-1)
Jump to Line
Something went wrong with that request. Please try again.