Skip to content

Commit

Permalink
Add three new TSRM api functions:
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
wez committed Apr 27, 2005
1 parent 396acbf commit 6d978a6
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 0 deletions.
90 changes: 90 additions & 0 deletions TSRM/TSRM.c
Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions TSRM/TSRM.h
Expand Up @@ -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)

Expand Down

0 comments on commit 6d978a6

Please sign in to comment.