Beispiel #1
0
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;
}
Beispiel #2
0
PJ_DEF(pj_pool_t*) pj_pool_create_on_buf(const char *name,
					 void *buf,
					 pj_size_t size)
{
#if PJ_HAS_POOL_ALT_API == 0
    struct creation_param param;
    long align_diff;

    PJ_ASSERT_RETURN(buf && size, NULL);

    if (!is_initialized) {
	if (pool_buf_initialize() != PJ_SUCCESS)
	    return NULL;
	is_initialized = 1;
    }

    /* Check and align buffer */
    align_diff = (long)buf;
    if (align_diff & (PJ_POOL_ALIGNMENT-1)) {
	align_diff &= (PJ_POOL_ALIGNMENT-1);
	buf = (void*) (((char*)buf) + align_diff);
	size -= align_diff;
    }

    param.stack_buf = buf;
    param.size = size;
    pj_thread_local_set(tls, &param);

    return pj_pool_create_int(&stack_based_factory, name, size, 0, 
			      pj_pool_factory_default_policy.callback);
#else
    PJ_UNUSED_ARG(buf);
    return pj_pool_create(NULL, name, size, size, NULL);
#endif
}
Beispiel #3
0
static DWORD WINAPI thread_main(void *param)
{
    pj_thread_t *rec = param;
    DWORD result;

#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
    rec->stk_start = (char*)&rec;
#endif

    if (pj_thread_local_set(thread_tls_id, rec) != PJ_SUCCESS) {
	pj_assert(!"TLS is not set (pj_init() error?)");
    }

    PJ_LOG(6,(rec->obj_name, "Thread started"));

    result = (*rec->proc)(rec->arg);

    PJ_LOG(6,(rec->obj_name, "Thread quitting"));
#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
    PJ_LOG(5,(rec->obj_name, "Thread stack max usage=%u by %s:%d", 
	      rec->stk_max_usage, rec->caller_file, rec->caller_line));
#endif

    return (DWORD)result;
}
Beispiel #4
0
/*
 * thread_main()
 *
 * This is the main entry for all threads.
 */
static void *thread_main(void *param)
{
    pj_thread_t *rec = (pj_thread_t*)param;
    void *result;
    pj_status_t rc;

#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK!=0
    rec->stk_start = (char*)&rec;
#endif

    /* Set current thread id. */
    rc = pj_thread_local_set(thread_tls_id, rec);
    if (rc != PJ_SUCCESS) {
	pj_assert(!"Thread TLS ID is not set (pj_init() error?)");
    }

    /* Check if suspension is required. */
    if (rec->suspended_mutex) {
	pj_mutex_lock(rec->suspended_mutex);
	pj_mutex_unlock(rec->suspended_mutex);
    }

    PJ_LOG(6,(rec->obj_name, "Thread started"));

    /* Call user's entry! */
    result = (void*)(long)(*rec->proc)(rec->arg);

    /* Done. */
    PJ_LOG(6,(rec->obj_name, "Thread quitting"));

    return result;
}
Beispiel #5
0
/* 
 * mod_ua_load()
 *
 * Called when module is being loaded by endpoint.
 */
static pj_status_t mod_ua_load(pjsip_endpoint *endpt)
{
    pj_status_t status;

    /* Initialize the user agent. */
    mod_ua.endpt = endpt;
    mod_ua.pool = pjsip_endpt_create_pool( endpt, "ua%p", PJSIP_POOL_LEN_UA,
					   PJSIP_POOL_INC_UA);
    if (mod_ua.pool == NULL)
	return PJ_ENOMEM;

    status = pj_mutex_create_recursive(mod_ua.pool, " ua%p", &mod_ua.mutex);
    if (status != PJ_SUCCESS)
	return status;

    mod_ua.dlg_table = pj_hash_create(mod_ua.pool, PJSIP_MAX_DIALOG_COUNT);
    if (mod_ua.dlg_table == NULL)
	return PJ_ENOMEM;

    pj_list_init(&mod_ua.free_dlgset_nodes);

    /* Initialize dialog lock. */
    status = pj_thread_local_alloc(&pjsip_dlg_lock_tls_id);
    if (status != PJ_SUCCESS)
	return status;

    pj_thread_local_set(pjsip_dlg_lock_tls_id, NULL);

    return PJ_SUCCESS;

}
Beispiel #6
0
/* This must be called in the context of the new thread. */
static void thread_initialize( pj_thread_t *thread )
{
    TRACE_((THIS_FILE, "---new thread initializing..."));

    /* Set TLS */
    pj_thread_local_set(thread_tls_id, thread);

    /* fill in thread structure */
    thread->thread = current;
    pj_assert(thread->thread != NULL);

    /* set signal mask to what we want to respond */
    siginitsetinv(&current->blocked, 
		  sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM));

    /* initialise wait queue */
    init_waitqueue_head(&thread->queue);

    /* initialise termination flag */
    thread->terminate = 0;

    /* set name of this process (making sure obj_name is null 
     * terminated first) 
     */
    thread->obj_name[PJ_MAX_OBJ_NAME-1] = '\0';
    sprintf(current->comm, thread->obj_name);
        
    /* tell the creator that we are ready and let him continue */
    up(&thread->startstop_sem);	
}
Beispiel #7
0
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);
}
Beispiel #8
0
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);
    }
}
Beispiel #9
0
/* 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;
}
Beispiel #10
0
/* 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);
}
Beispiel #11
0
/*
 * 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;
}
Beispiel #12
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);
}
Beispiel #13
0
static DWORD WINAPI thread_main(void *param)
{
    pj_thread_t *rec = param;
    void *result;

    PJ_LOG(6,(rec->obj_name, "Thread started"));

    pj_thread_local_set(thread_tls_id, rec);
    result = (*rec->proc)(rec->arg);

    PJ_LOG(6,(rec->obj_name, "Thread quitting"));
    return (DWORD)result;
}
Beispiel #14
0
/* Resume logging facility for this thread */
static void resume_logging(int *saved_level)
{
#if PJ_HAS_THREADS
    if (thread_suspended_tls_id != -1) 
    {
	pj_thread_local_set(thread_suspended_tls_id, (void*)PJ_FALSE);
    }
    else
#endif
    {
	/* Only revert the level if application doesn't change the
	 * logging level between suspend and resume.
	 */
	if (pj_log_max_level==0 && *saved_level)
	    pj_log_max_level = *saved_level;
    }
}
Beispiel #15
0
/* Temporarily suspend logging facility for this thread.
 * If thread local storage/variable is not used or not initialized, then
 * we can only suspend the logging globally across all threads. This may
 * happen e.g. when log function is called before PJLIB is fully initialized
 * or after PJLIB is shutdown.
 */
static void suspend_logging(int *saved_level)
{
	/* Save the level regardless, just in case PJLIB is shutdown
	 * between suspend and resume.
	 */
	*saved_level = pj_log_max_level;

#if PJ_HAS_THREADS
    if (thread_suspended_tls_id != -1) 
    {
	pj_thread_local_set(thread_suspended_tls_id, (void*)PJ_TRUE);
    } 
    else
#endif
    {
	pj_log_max_level = 0;
    }
}
Beispiel #16
0
pj_status_t pj_thread_init(void)
{
#if PJ_HAS_THREADS
    pj_memset(&main_thread, 0, sizeof(main_thread));
    main_thread.thread = pthread_self();
    sprintf(main_thread.obj_name, "thr%p", &main_thread);

    thread_tls_id = pj_thread_local_alloc();
    if (thread_tls_id == -1) {
	return -1;
    }

    pj_thread_local_set(thread_tls_id, &main_thread);
    return PJ_OK;
#else
    PJ_LOG(2,(THIS_FILE, "Thread init error. Threading is not enabled!"));
    return -1;
#endif
}
Beispiel #17
0
PJ_DEF(pj_pool_t*) pj_pool_create_on_buf(const char *name,
					 void *buf,
					 pj_size_t size)
{
    struct creation_param param;

    PJ_ASSERT_RETURN(buf && size, NULL);

    if (!is_initialized) {
	if (pool_buf_initialize() != PJ_SUCCESS)
	    return NULL;
	is_initialized = 1;
    }

    param.stack_buf = buf;
    param.size = size;
    pj_thread_local_set(tls, &param);

    return pj_pool_create_int(&stack_based_factory, name, size, 0, 
			      pj_pool_factory_default_policy.callback);
}
Beispiel #18
0
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;
}
Beispiel #19
0
/*
 * 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
}
Beispiel #20
0
 //
 // Set thread specific data.
 //
 static pj_status_t set(long index, void *value)
 {
     return pj_thread_local_set(index, value);
 }
static void log_set_indent(int indent)
{
    if (indent < 0) indent = 0;
    pj_thread_local_set(thread_indent_tls_id, (void*)(long)indent);
}