⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_core_unix.c

📁 一个开源SIP协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
#else
    PJ_LOG(6,(mutex->obj_name, "Mutex: thread %s is waiting", 
				pj_thread_this()->obj_name));
#endif

    status = pthread_mutex_lock( &mutex->mutex );


#if PJ_DEBUG
    if (status == PJ_SUCCESS) {
	mutex->owner = pj_thread_this();
	pj_ansi_strcpy(mutex->owner_name, mutex->owner->obj_name);
	++mutex->nesting_level;
    }

    PJ_LOG(6,(mutex->obj_name, 
	      (status==0 ? 
		"Mutex acquired by thread %s (level=%d)" : 
		"Mutex acquisition FAILED by %s (level=%d)"),
	      pj_thread_this()->obj_name,
	      mutex->nesting_level));
#else
    PJ_LOG(6,(mutex->obj_name, 
	      (status==0 ? "Mutex acquired by thread %s" : "FAILED by %s"),
	      pj_thread_this()->obj_name));
#endif

    if (status == 0)
	return PJ_SUCCESS;
    else
	return PJ_RETURN_OS_ERROR(status);
#else	/* PJ_HAS_THREADS */
    pj_assert( mutex == (pj_mutex_t*)1 );
    return PJ_SUCCESS;
#endif
}

/*
 * pj_mutex_unlock()
 */
PJ_DEF(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex)
{
#if PJ_HAS_THREADS
    pj_status_t status;

    PJ_CHECK_STACK();
    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);

#if PJ_DEBUG
    pj_assert(mutex->owner == pj_thread_this());
    if (--mutex->nesting_level == 0) {
	mutex->owner = NULL;
	mutex->owner_name[0] = '\0';
    }

    PJ_LOG(6,(mutex->obj_name, "Mutex released by thread %s (level=%d)", 
				pj_thread_this()->obj_name, 
				mutex->nesting_level));
#else
    PJ_LOG(6,(mutex->obj_name, "Mutex released by thread %s", 
				pj_thread_this()->obj_name));
#endif

    status = pthread_mutex_unlock( &mutex->mutex );
    if (status == 0)
	return PJ_SUCCESS;
    else
	return PJ_RETURN_OS_ERROR(status);

#else /* PJ_HAS_THREADS */
    pj_assert( mutex == (pj_mutex_t*)1 );
    return PJ_SUCCESS;
#endif
}

/*
 * pj_mutex_trylock()
 */
PJ_DEF(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex)
{
#if PJ_HAS_THREADS
    int status;

    PJ_CHECK_STACK();
    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);

    status = pthread_mutex_trylock( &mutex->mutex );

    if (status==0) {
#if PJ_DEBUG
	mutex->owner = pj_thread_this();
	pj_ansi_strcpy(mutex->owner_name, mutex->owner->obj_name);
	++mutex->nesting_level;

	PJ_LOG(6,(mutex->obj_name, "Mutex acquired by thread %s (level=%d)", 
				   pj_thread_this()->obj_name,
				   mutex->nesting_level));
#else
	PJ_LOG(6,(mutex->obj_name, "Mutex acquired by thread %s", 
				  pj_thread_this()->obj_name));
#endif
    }
    
    if (status==0)
	return PJ_SUCCESS;
    else
	return PJ_RETURN_OS_ERROR(status);
#else	/* PJ_HAS_THREADS */
    pj_assert( mutex == (pj_mutex_t*)1);
    return PJ_SUCCESS;
#endif
}

/*
 * pj_mutex_destroy()
 */
PJ_DEF(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex)
{
    enum { RETRY = 4 };
    int status = 0;
    unsigned retry;

    PJ_CHECK_STACK();
    PJ_ASSERT_RETURN(mutex, PJ_EINVAL);

#if PJ_HAS_THREADS
    PJ_LOG(6,(mutex->obj_name, "Mutex destroyed by thread %s",
			       pj_thread_this()->obj_name));

    for (retry=0; retry<RETRY; ++retry) {
	status = pthread_mutex_destroy( &mutex->mutex );
	if (status == PJ_SUCCESS)
	    break;
	else if (retry<RETRY-1 && status == EBUSY)
	    pthread_mutex_unlock(&mutex->mutex);
    }

    if (status == 0)
	return PJ_SUCCESS;
    else {
	pj_assert(!"Error destroying pthread_mutex");
	return PJ_RETURN_OS_ERROR(status);
    }
#else
    pj_assert( mutex == (pj_mutex_t*)1 );
    status = PJ_SUCCESS;
    return status;
#endif
}

#if PJ_DEBUG
PJ_DEF(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex)
{
#if PJ_HAS_THREADS
    return mutex->owner == pj_thread_this();
#else
    return 1;
#endif
}
#endif

///////////////////////////////////////////////////////////////////////////////
/*
 * Include Read/Write mutex emulation for POSIX platforms that lack it (e.g.
 * RTEMS). Otherwise use POSIX rwlock.
 */
#if defined(PJ_EMULATE_RWMUTEX) && PJ_EMULATE_RWMUTEX!=0
#  include "os_rwmutex.c"
#else
struct pj_rwmutex_t
{
    pthread_rwlock_t rwlock;
};

PJ_DEF(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,
				      pj_rwmutex_t **p_mutex)
{
    pj_rwmutex_t *rwm;
    pj_status_t status;

    PJ_UNUSED_ARG(name);
    
    rwm = pj_pool_alloc(pool, sizeof(pj_rwmutex_t));
    PJ_ASSERT_RETURN(rwm, PJ_ENOMEM);

    status = pthread_rwlock_init(&rwm->rwlock, NULL);
    if (status != 0)
	return PJ_RETURN_OS_ERROR(status);

    *p_mutex = rwm;
    return PJ_SUCCESS;
}

/*
 * Lock the mutex for reading.
 *
 */
PJ_DEF(pj_status_t) pj_rwmutex_lock_read(pj_rwmutex_t *mutex)
{
    pj_status_t status;

    status = pthread_rwlock_rdlock(&mutex->rwlock);
    if (status != 0)
	return PJ_RETURN_OS_ERROR(status);

    return PJ_SUCCESS;
}

/*
 * Lock the mutex for writing.
 *
 */
PJ_DEF(pj_status_t) pj_rwmutex_lock_write(pj_rwmutex_t *mutex)
{
    pj_status_t status;

    status = pthread_rwlock_wrlock(&mutex->rwlock);
    if (status != 0)
	return PJ_RETURN_OS_ERROR(status);

    return PJ_SUCCESS;
}

/*
 * Release read lock.
 *
 */
PJ_DEF(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex)
{
    return pj_rwmutex_unlock_write(mutex);
}

/*
 * Release write lock.
 *
 */
PJ_DEF(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex)
{
    pj_status_t status;

    status = pthread_rwlock_unlock(&mutex->rwlock);
    if (status != 0)
	return PJ_RETURN_OS_ERROR(status);

    return PJ_SUCCESS;
}

/*
 * Destroy reader/writer mutex.
 *
 */
PJ_DEF(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex)
{
    pj_status_t status;

    status = pthread_rwlock_destroy(&mutex->rwlock);
    if (status != 0)
	return PJ_RETURN_OS_ERROR(status);

    return PJ_SUCCESS;
}

#endif	/* PJ_EMULATE_RWMUTEX */


///////////////////////////////////////////////////////////////////////////////
#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0

/*
 * pj_sem_create()
 */
PJ_DEF(pj_status_t) pj_sem_create( pj_pool_t *pool, 
				   const char *name,
				   unsigned initial, 
				   unsigned max,
				   pj_sem_t **ptr_sem)
{
#if PJ_HAS_THREADS
    pj_sem_t *sem;

    PJ_CHECK_STACK();
    PJ_ASSERT_RETURN(pool != NULL && ptr_sem != NULL, PJ_EINVAL);

    sem = pj_pool_alloc(pool, sizeof(*sem));
    PJ_ASSERT_RETURN(sem, PJ_ENOMEM);

    if (sem_init( &sem->sem, 0, initial) != 0) 
	return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
    
    /* Set name. */
    if (!name) {
	name = "sem%p";
    }
    if (strchr(name, '%')) {
	pj_ansi_snprintf(sem->obj_name, PJ_MAX_OBJ_NAME, name, sem);
    } else {
	strncpy(sem->obj_name, name, PJ_MAX_OBJ_NAME);
	sem->obj_name[PJ_MAX_OBJ_NAME-1] = '\0';
    }

    PJ_LOG(6, (sem->obj_name, "Semaphore created"));

    *ptr_sem = sem;
    return PJ_SUCCESS;
#else
    *ptr_sem = (pj_sem_t*)1;
    return PJ_SUCCESS;
#endif
}

/*
 * pj_sem_wait()
 */
PJ_DEF(pj_status_t) pj_sem_wait(pj_sem_t *sem)
{
#if PJ_HAS_THREADS
    int result;

    PJ_CHECK_STACK();
    PJ_ASSERT_RETURN(sem, PJ_EINVAL);

    PJ_LOG(6, (sem->obj_name, "Semaphore: thread %s is waiting", 
			      pj_thread_this()->obj_name));

    result = sem_wait( &sem->sem );
    
    if (result == 0) {
	PJ_LOG(6, (sem->obj_name, "Semaphore acquired by thread %s", 
				  pj_thread_this()->obj_name));
    } else {
	PJ_LOG(6, (sem->obj_name, "Semaphore: thread %s FAILED to acquire", 
				  pj_thread_this()->obj_name));
    }

    if (result == 0)
	return PJ_SUCCESS;
    else
	return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
#else
    pj_assert( sem == (pj_sem_t*) 1 );
    return PJ_SUCCESS;
#endif
}

/*
 * pj_sem_trywait()
 */
PJ_DEF(pj_status_t) pj_sem_trywait(pj_sem_t *sem)
{
#if PJ_HAS_THREADS
    int result;

    PJ_CHECK_STACK();
    PJ_ASSERT_RETURN(sem, PJ_EINVAL);

    result = sem_trywait( &sem->sem );
    
    if (result == 0) {
	PJ_LOG(6, (sem->obj_name, "Semaphore acquired by thread %s", 
				  pj_thread_this()->obj_name));
    } 
    if (result == 0)
	return PJ_SUCCESS;
    else
	return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
#else
    pj_assert( sem == (pj_sem_t*)1 );
    return PJ_SUCCESS;
#endif
}

/*
 * pj_sem_post()
 */
PJ_DEF(pj_status_t) pj_sem_post(pj_sem_t *sem)
{
#if PJ_HAS_THREADS
    int result;
    PJ_LOG(6, (sem->obj_name, "Semaphore released by thread %s",
			      pj_thread_this()->obj_name));
    result = sem_post( &sem->sem );

    if (result == 0)
	return PJ_SUCCESS;
    else
	return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
#else
    pj_assert( sem == (pj_sem_t*) 1);
    return PJ_SUCCESS;
#endif
}

/*
 * pj_sem_destroy()
 */
PJ_DEF(pj_status_t) pj_sem_destroy(pj_sem_t *sem)
{
#if PJ_HAS_THREADS
    int result;

    PJ_CHECK_STACK();
    PJ_ASSERT_RETURN(sem, PJ_EINVAL);

    PJ_LOG(6, (sem->obj_name, "Semaphore destroyed by thread %s",
			      pj_thread_this()->obj_name));
    result = sem_destroy( &sem->sem );

    if (result == 0)
	return PJ_SUCCESS;
    else
	return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
#else
    pj_assert( sem == (pj_sem_t*) 1 );
    return PJ_SUCCESS;
#endif
}

#endif	/* PJ_HAS_SEMAPHORE */

///////////////////////////////////////////////////////////////////////////////
#if defined(PJ_HAS_EVENT_OBJ) && PJ_HAS_EVENT_OBJ != 0

/*
 * pj_event_create()
 */
PJ_DEF(pj_status_t) pj_event_create(pj_pool_t *pool, const char *name,
				    pj_bool_t manual_reset, pj_bool_t initial,
				    pj_event_t **ptr_event)
{
    pj_assert(!"Not supported!");
    PJ_UNUSED_ARG(pool);
    PJ_UNUSED_ARG(name);
    PJ_UNUSED_ARG(manual_reset);
    PJ_UNUSED_ARG(initial);
    PJ_UNUSED_ARG(ptr_event);
    return PJ_EINVALIDOP;
}

/*
 * pj_event_wait()
 */
PJ_DEF(pj_status_t) pj_event_wait(pj_event_t *event)
{
    PJ_UNUSED_ARG(event);
    return PJ_EINVALIDOP;
}

/*
 * pj_event_trywait()
 */
PJ_DEF(pj_status_t) pj_event_trywait(pj_event_t *event)
{
    PJ_UNUSED_ARG(event);
    return PJ_EINVALIDOP;
}

/*
 * pj_event_set()
 */
PJ_DEF(pj_status_t) pj_event_set(pj_event_t *event)
{
    PJ_UNUSED_ARG(event);
    return PJ_EINVALIDOP;
}

/*
 * pj_event_pulse()
 */
PJ_DEF(pj_status_t) pj_event_pulse(pj_event_t *event)
{
    PJ_UNUSED_ARG(event);
    return PJ_EINVALIDOP;
}

/*
 * pj_event_reset()
 */
PJ_DEF(pj_status_t) pj_event_reset(pj_event_t *event)
{
    PJ_UNUSED_ARG(event);
    return PJ_EINVALIDOP;
}

/*
 * pj_event_destroy()
 */
PJ_DEF(pj_status_t) pj_event_destroy(pj_event_t *event)
{
    PJ_UNUSED_ARG(event);
    return PJ_EINVALIDOP;
}

#endif	/* PJ_HAS_EVENT_OBJ */

///////////////////////////////////////////////////////////////////////////////
#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0
/*
 * Terminal
 */

/**
 * Set terminal color.
 */
PJ_DEF(pj_status_t) pj_term_set_color(pj_color_t color)
{
    PJ_UNUSED_ARG(color);
    return PJ_EINVALIDOP;
}

/**
 * Get current terminal foreground color.
 */
PJ_DEF(pj_color_t) pj_term_get_color(void)
{
    return 0;
}

#endif	/* PJ_TERM_HAS_COLOR */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -