-
Notifications
You must be signed in to change notification settings - Fork 137
/
tsrm_5.0.diff
179 lines (172 loc) · 5.69 KB
/
tsrm_5.0.diff
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)