PJ_DEF(pj_thread_t*) pj_thread_register (const char *cstr_thread_name, pj_thread_desc desc) { pj_thread_t *thread = (pj_thread_t *)desc; pj_str_t thread_name = pj_str((char*)cstr_thread_name); /* Size sanity check. */ if (sizeof(pj_thread_desc) < sizeof(pj_thread_t)) { pj_assert(!"Not enough pj_thread_desc size!"); return NULL; } /* If a thread descriptor has been registered before, just return it. */ if (pj_thread_local_get (thread_tls_id) != 0) { return (pj_thread_t*)pj_thread_local_get (thread_tls_id); } /* Initialize and set the thread entry. */ pj_memset(desc, 0, sizeof(pj_thread_desc)); thread->hthread = GetCurrentThread(); thread->idthread = GetCurrentThreadId(); if (cstr_thread_name && pj_strlen(&thread_name) < sizeof(thread->obj_name)-1) sprintf(thread->obj_name, cstr_thread_name, thread->idthread); else sprintf(thread->obj_name, "thr%p", (void*)thread->idthread); pj_thread_local_set(thread_tls_id, thread); return thread; }
/* * pj_thread_this() */ PJ_DEF(pj_thread_t*) pj_thread_this(int inst_id) { #if PJ_HAS_THREADS pj_thread_t *rec; if (inst_id != 1) PJ_LOG(6, (THIS_FILE, "pj_thread_this() thrad_tls_id[%d]", inst_id)); rec = (pj_thread_t*)pj_thread_local_get(thread_tls_id[inst_id]); if (rec == NULL) { pj_assert(!"Calling pjlib from unknown/external thread. You must " "register external threads with pj_thread_register() " "before calling any pjlib functions."); } /* * MUST NOT check stack because this function is called * by PJ_CHECK_STACK() itself!!! * */ return rec; #else pj_assert(!"Threading is not enabled!"); return NULL; #endif }
PJ_DEF(void) pj_pop_exception_handler_(void) { struct pj_exception_state_t *handler; handler = pj_thread_local_get(thread_local_id); pj_assert(handler != NULL); pj_thread_local_set(thread_local_id, handler->prev); }
/* * Check if this thread has been registered to PJLIB. */ PJ_DEF(pj_bool_t) pj_thread_is_registered(void) { #if PJ_HAS_THREADS return pj_thread_local_get(thread_tls_id) != 0; #else pj_assert("pj_thread_is_registered() called in non-threading mode!"); return PJ_TRUE; #endif }
PJ_DEF(void) pj_pop_exception_handler_(struct pj_exception_state_t *rec) { struct pj_exception_state_t *handler; handler = (struct pj_exception_state_t *) pj_thread_local_get(thread_local_id); if (handler && handler==rec) { pj_thread_local_set(thread_local_id, handler->prev); } }
/* Carefully unlock dialog mutex, protect against situation when the dialog * has already been destroyed. */ static pj_status_t unlock_dialog(pjsip_dlg *dlg, struct dialog_lock_data *lck) { pj_assert(pj_thread_local_get(pjsip_dlg_lock_tls_id) == lck); pj_assert(dlg == lck->dlg); pj_thread_local_set(pjsip_dlg_lock_tls_id, lck->prev); if (lck->is_alive) pj_mutex_unlock(dlg->mutex); return lck->is_alive ? 0 : -1; }
/* Lock dialog mutex. */ static void lock_dialog(pjsip_dlg *dlg, struct dialog_lock_data *lck) { struct dialog_lock_data *prev; pj_mutex_lock(dlg->mutex); prev = pj_thread_local_get(pjsip_dlg_lock_tls_id); lck->prev = prev; lck->dlg = dlg; lck->is_alive = 1; pj_thread_local_set(pjsip_dlg_lock_tls_id, lck); }
PJ_DEF(pj_thread_t*) pj_thread_this(void) { #if PJ_HAS_THREADS pj_thread_t *rec = pj_thread_local_get(thread_tls_id); pj_assert(rec != NULL); return rec; #else PJ_LOG(2, (THIS_FILE, "pj_thread_this() unsupported: thread is not enabled!")); return 0; #endif }
/* * pj_thread_register(..) */ PJ_DEF(pj_status_t) pj_thread_register ( const char *cstr_thread_name, pj_thread_desc desc, pj_thread_t **thread_ptr) { char stack_ptr; pj_status_t rc; pj_thread_t *thread = (pj_thread_t *)desc; pj_str_t thread_name = pj_str((char*)cstr_thread_name); /* Size sanity check. */ if (sizeof(pj_thread_desc) < sizeof(pj_thread_t)) { pj_assert(!"Not enough pj_thread_desc size!"); return PJ_EBUG; } /* If a thread descriptor has been registered before, just return it. */ if (pj_thread_local_get (thread_tls_id) != 0) { // 2006-02-26 bennylp: // This wouldn't work in all cases!. // If thread is created by external module (e.g. sound thread), // thread may be reused while the pool used for the thread descriptor // has been deleted by application. //*thread_ptr = (pj_thread_t*)pj_thread_local_get (thread_tls_id); //return PJ_SUCCESS; } /* Initialize and set the thread entry. */ pj_bzero(desc, sizeof(struct pj_thread_t)); thread->hthread = GetCurrentThread(); thread->idthread = GetCurrentThreadId(); #if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0 thread->stk_start = &stack_ptr; thread->stk_size = 0xFFFFFFFFUL; thread->stk_max_usage = 0; #else stack_ptr = '\0'; #endif if (cstr_thread_name && pj_strlen(&thread_name) < sizeof(thread->obj_name)-1) pj_ansi_snprintf(thread->obj_name, sizeof(thread->obj_name), cstr_thread_name, thread->idthread); else pj_ansi_snprintf(thread->obj_name, sizeof(thread->obj_name), "thr%p", (void*)(pj_ssize_t)thread->idthread); rc = pj_thread_local_set(thread_tls_id, thread); if (rc != PJ_SUCCESS) return rc; *thread_ptr = thread; return PJ_SUCCESS; }
PJ_DEF(void) pj_throw_exception_(int exception_id) { struct pj_exception_state_t *handler; handler = pj_thread_local_get(thread_local_id); if (handler == NULL) { PJ_LOG(1,("except.c", "!!!FATAL: unhandled exception %s!\n", pj_exception_id_name(exception_id))); pj_assert(handler != NULL); /* This will crash the system! */ } pj_longjmp(handler->state, exception_id); }
/* Is logging facility suspended for this thread? */ static pj_bool_t is_logging_suspended(void) { #if PJ_HAS_THREADS if (thread_suspended_tls_id != -1) { return pj_thread_local_get(thread_suspended_tls_id) != NULL; } else #endif { return pj_log_max_level == 0; } }
PJ_DEF(void) pj_push_exception_handler_(struct pj_exception_state_t *rec) { struct pj_exception_state_t *parent_handler = NULL; if (thread_local_id == -1) { pj_thread_local_alloc(&thread_local_id); pj_assert(thread_local_id != -1); pj_atexit(&exception_cleanup); } parent_handler = pj_thread_local_get(thread_local_id); rec->prev = parent_handler; pj_thread_local_set(thread_local_id, rec); }
/* * pj_thread_this() */ PJ_DEF(pj_thread_t*) pj_thread_this(void) { pj_thread_t *rec = pj_thread_local_get(thread_tls_id); if (rec == NULL) { pj_assert(!"Calling pjlib from unknown/external thread. You must " "register external threads with pj_thread_register() " "before calling any pjlib functions."); } /* * MUST NOT check stack because this function is called * by PJ_CHECK_STACK() itself!!! * */ return rec; }
static void* stack_alloc(pj_pool_factory *factory, pj_size_t size) { struct creation_param *param; void *buf; PJ_UNUSED_ARG(factory); param = (struct creation_param*) pj_thread_local_get(tls); if (param == NULL) { /* Don't assert(), this is normal no-memory situation */ return NULL; } pj_thread_local_set(tls, NULL); PJ_ASSERT_RETURN(size <= param->size, NULL); buf = param->stack_buf; /* Prevent the buffer from being reused */ param->stack_buf = NULL; return buf; }
/* * Check if this thread has been registered to PJLIB. */ PJ_DEF(pj_bool_t) pj_thread_is_registered(void) { return pj_thread_local_get(thread_tls_id) != 0; }
// // Get thread specific data. // static void *get(long index) { return pj_thread_local_get(index); }
PJ_DEF(pj_thread_t*) pj_thread_this(void) { return (pj_thread_t*)pj_thread_local_get(thread_tls_id); }
/* * pj_thread_register(..) */ PJ_DEF(pj_status_t) pj_thread_register ( const char *cstr_thread_name, pj_thread_desc desc, pj_thread_t **ptr_thread) { #if PJ_HAS_THREADS char stack_ptr; pj_status_t rc; pj_thread_t *thread = (pj_thread_t *)desc; pj_str_t thread_name = pj_str((char*)cstr_thread_name); /* Size sanity check. */ if (sizeof(pj_thread_desc) < sizeof(pj_thread_t)) { pj_assert(!"Not enough pj_thread_desc size!"); return PJ_EBUG; } /* Warn if this thread has been registered before */ if (pj_thread_local_get (thread_tls_id) != 0) { // 2006-02-26 bennylp: // This wouldn't work in all cases!. // If thread is created by external module (e.g. sound thread), // thread may be reused while the pool used for the thread descriptor // has been deleted by application. //*thread_ptr = (pj_thread_t*)pj_thread_local_get (thread_tls_id); //return PJ_SUCCESS; PJ_LOG(4,(THIS_FILE, "Info: possibly re-registering existing " "thread")); } /* On the other hand, also warn if the thread descriptor buffer seem to * have been used to register other threads. */ pj_assert(thread->signature1 != SIGNATURE1 || thread->signature2 != SIGNATURE2 || (thread->thread == pthread_self())); /* Initialize and set the thread entry. */ pj_bzero(desc, sizeof(struct pj_thread_t)); thread->thread = pthread_self(); thread->signature1 = SIGNATURE1; thread->signature2 = SIGNATURE2; if(cstr_thread_name && pj_strlen(&thread_name) < sizeof(thread->obj_name)-1) pj_ansi_snprintf(thread->obj_name, sizeof(thread->obj_name), cstr_thread_name, thread->thread); else pj_ansi_snprintf(thread->obj_name, sizeof(thread->obj_name), "thr%p", (void*)thread->thread); rc = pj_thread_local_set(thread_tls_id, thread); if (rc != PJ_SUCCESS) { pj_bzero(desc, sizeof(struct pj_thread_t)); return rc; } #if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0 thread->stk_start = &stack_ptr; thread->stk_size = 0xFFFFFFFFUL; thread->stk_max_usage = 0; #else stack_ptr = '\0'; #endif *ptr_thread = thread; return PJ_SUCCESS; #else pj_thread_t *thread = (pj_thread_t*)desc; *ptr_thread = thread; return PJ_SUCCESS; #endif }
static int log_get_raw_indent(void) { return (long)pj_thread_local_get(thread_indent_tls_id); }
PJ_DEF(pj_thread_t*) pj_thread_this(void) { pj_thread_t *rec = pj_thread_local_get(thread_tls_id); pj_assert(rec != NULL); return rec; }