📄 os_core_unix.c
字号:
#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_DEBUGPJ_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"#elsestruct 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 + -