Skip to content
This repository
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

file 179 lines (172 sloc) 5.824 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
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)
 
Something went wrong with that request. Please try again.