📄 os_core_win32.c
字号:
/*
* MUST NOT check stack because this function is called
* by PJ_CHECK_STACK() itself!!!
*
*/
return rec;
}
/*
* pj_thread_join()
*/
PJ_DEF(pj_status_t) pj_thread_join(pj_thread_t *p)
{
pj_thread_t *rec = (pj_thread_t *)p;
DWORD rc;
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(p, PJ_EINVAL);
PJ_LOG(6, (pj_thread_this()->obj_name, "Joining thread %s", p->obj_name));
rc = WaitForSingleObject(rec->hthread, INFINITE);
if (rc==WAIT_OBJECT_0)
return PJ_SUCCESS;
else if (rc==WAIT_TIMEOUT)
return PJ_ETIMEDOUT;
else
return PJ_RETURN_OS_ERROR(GetLastError());
}
/*
* pj_thread_destroy()
*/
PJ_DEF(pj_status_t) pj_thread_destroy(pj_thread_t *p)
{
pj_thread_t *rec = (pj_thread_t *)p;
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(p, PJ_EINVAL);
if (CloseHandle(rec->hthread) == TRUE)
return PJ_SUCCESS;
else
return PJ_RETURN_OS_ERROR(GetLastError());
}
/*
* pj_thread_sleep()
*/
PJ_DEF(pj_status_t) pj_thread_sleep(unsigned msec)
{
PJ_CHECK_STACK();
Sleep(msec);
return PJ_SUCCESS;
}
#if defined(PJ_OS_HAS_CHECK_STACK) && PJ_OS_HAS_CHECK_STACK != 0
/*
* pj_thread_check_stack()
* Implementation for PJ_CHECK_STACK()
*/
PJ_DEF(void) pj_thread_check_stack(const char *file, int line)
{
char stk_ptr;
pj_uint32_t usage;
pj_thread_t *thread = pj_thread_this();
pj_assert(thread);
/* Calculate current usage. */
usage = (&stk_ptr > thread->stk_start) ? &stk_ptr - thread->stk_start :
thread->stk_start - &stk_ptr;
/* Assert if stack usage is dangerously high. */
pj_assert("STACK OVERFLOW!! " && (usage <= thread->stk_size - 128));
/* Keep statistic. */
if (usage > thread->stk_max_usage) {
thread->stk_max_usage = usage;
thread->caller_file = file;
thread->caller_line = line;
}
}
/*
* pj_thread_get_stack_max_usage()
*/
PJ_DEF(pj_uint32_t) pj_thread_get_stack_max_usage(pj_thread_t *thread)
{
return thread->stk_max_usage;
}
/*
* pj_thread_get_stack_info()
*/
PJ_DEF(pj_status_t) pj_thread_get_stack_info( pj_thread_t *thread,
const char **file,
int *line )
{
pj_assert(thread);
*file = thread->caller_file;
*line = thread->caller_line;
return 0;
}
#endif /* PJ_OS_HAS_CHECK_STACK */
///////////////////////////////////////////////////////////////////////////////
/*
* pj_atomic_create()
*/
PJ_DEF(pj_status_t) pj_atomic_create( pj_pool_t *pool,
pj_atomic_value_t initial,
pj_atomic_t **atomic_ptr)
{
pj_atomic_t *atomic_var = pj_pool_alloc(pool, sizeof(pj_atomic_t));
if (!atomic_var)
return PJ_ENOMEM;
atomic_var->value = initial;
*atomic_ptr = atomic_var;
return PJ_SUCCESS;
}
/*
* pj_atomic_destroy()
*/
PJ_DEF(pj_status_t) pj_atomic_destroy( pj_atomic_t *var )
{
PJ_UNUSED_ARG(var);
PJ_ASSERT_RETURN(var, PJ_EINVAL);
return 0;
}
/*
* pj_atomic_set()
*/
PJ_DEF(void) pj_atomic_set( pj_atomic_t *atomic_var, pj_atomic_value_t value)
{
PJ_CHECK_STACK();
InterlockedExchange(&atomic_var->value, value);
}
/*
* pj_atomic_get()
*/
PJ_DEF(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var)
{
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(atomic_var, 0);
return atomic_var->value;
}
/*
* pj_atomic_inc_and_get()
*/
PJ_DEF(pj_atomic_value_t) pj_atomic_inc_and_get(pj_atomic_t *atomic_var)
{
PJ_CHECK_STACK();
#if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400
return InterlockedIncrement(&atomic_var->value);
#else
return InterlockedIncrement(&atomic_var->value);
#endif
}
/*
* pj_atomic_inc()
*/
PJ_DEF(void) pj_atomic_inc(pj_atomic_t *atomic_var)
{
pj_atomic_inc_and_get(atomic_var);
}
/*
* pj_atomic_dec_and_get()
*/
PJ_DEF(pj_atomic_value_t) pj_atomic_dec_and_get(pj_atomic_t *atomic_var)
{
PJ_CHECK_STACK();
#if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400
return InterlockedDecrement(&atomic_var->value);
#else
return InterlockedDecrement(&atomic_var->value);
#endif
}
/*
* pj_atomic_dec()
*/
PJ_DEF(void) pj_atomic_dec(pj_atomic_t *atomic_var)
{
pj_atomic_dec_and_get(atomic_var);
}
/*
* pj_atomic_add()
*/
PJ_DEF(void) pj_atomic_add( pj_atomic_t *atomic_var,
pj_atomic_value_t value )
{
#if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400
InterlockedExchangeAdd( &atomic_var->value, value );
#else
InterlockedExchangeAdd( &atomic_var->value, value );
#endif
}
/*
* pj_atomic_add_and_get()
*/
PJ_DEF(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,
pj_atomic_value_t value)
{
#if defined(PJ_WIN32_WINNT) && PJ_WIN32_WINNT >= 0x0400
long oldValue = InterlockedExchangeAdd( &atomic_var->value, value);
return oldValue + value;
#else
long oldValue = InterlockedExchangeAdd( &atomic_var->value, value);
return oldValue + value;
#endif
}
///////////////////////////////////////////////////////////////////////////////
/*
* pj_thread_local_alloc()
*/
PJ_DEF(pj_status_t) pj_thread_local_alloc(long *index)
{
PJ_ASSERT_RETURN(index != NULL, PJ_EINVAL);
//Can't check stack because this function is called in the
//beginning before main thread is initialized.
//PJ_CHECK_STACK();
*index = TlsAlloc();
if (*index == TLS_OUT_OF_INDEXES)
return PJ_RETURN_OS_ERROR(GetLastError());
else
return PJ_SUCCESS;
}
/*
* pj_thread_local_free()
*/
PJ_DEF(void) pj_thread_local_free(long index)
{
PJ_CHECK_STACK();
TlsFree(index);
}
/*
* pj_thread_local_set()
*/
PJ_DEF(pj_status_t) pj_thread_local_set(long index, void *value)
{
BOOL rc;
//Can't check stack because this function is called in the
//beginning before main thread is initialized.
//PJ_CHECK_STACK();
rc = TlsSetValue(index, value);
return rc!=0 ? PJ_SUCCESS : PJ_RETURN_OS_ERROR(GetLastError());
}
/*
* pj_thread_local_get()
*/
PJ_DEF(void*) pj_thread_local_get(long index)
{
//Can't check stack because this function is called
//by PJ_CHECK_STACK() itself!!!
//PJ_CHECK_STACK();
return TlsGetValue(index);
}
///////////////////////////////////////////////////////////////////////////////
static pj_status_t init_mutex(pj_mutex_t *mutex, const char *name)
{
PJ_CHECK_STACK();
#if PJ_WIN32_WINNT >= 0x0400
InitializeCriticalSection(&mutex->crit);
#else
mutex->hMutex = CreateMutex(NULL, FALSE, NULL);
if (!mutex->hMutex) {
return PJ_RETURN_OS_ERROR(GetLastError());
}
#endif
#if PJ_DEBUG
/* Set owner. */
mutex->nesting_level = 0;
mutex->owner = NULL;
#endif
/* Set name. */
if (!name) {
name = "mtx%p";
}
if (strchr(name, '%')) {
pj_ansi_snprintf(mutex->obj_name, PJ_MAX_OBJ_NAME, name, mutex);
} else {
pj_ansi_strncpy(mutex->obj_name, name, PJ_MAX_OBJ_NAME);
mutex->obj_name[PJ_MAX_OBJ_NAME-1] = '\0';
}
PJ_LOG(6, (mutex->obj_name, "Mutex created"));
return PJ_SUCCESS;
}
/*
* pj_mutex_create()
*/
PJ_DEF(pj_status_t) pj_mutex_create(pj_pool_t *pool,
const char *name,
int type,
pj_mutex_t **mutex_ptr)
{
pj_status_t rc;
pj_mutex_t *mutex;
PJ_UNUSED_ARG(type);
PJ_ASSERT_RETURN(pool && mutex_ptr, PJ_EINVAL);
mutex = pj_pool_alloc(pool, sizeof(*mutex));
if (!mutex)
return PJ_ENOMEM;
rc = init_mutex(mutex, name);
if (rc != PJ_SUCCESS)
return rc;
*mutex_ptr = mutex;
return PJ_SUCCESS;
}
/*
* pj_mutex_create_simple()
*/
PJ_DEF(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool,
const char *name,
pj_mutex_t **mutex )
{
return pj_mutex_create(pool, name, PJ_MUTEX_SIMPLE, mutex);
}
/*
* pj_mutex_create_recursive()
*/
PJ_DEF(pj_status_t) pj_mutex_create_recursive( pj_pool_t *pool,
const char *name,
pj_mutex_t **mutex )
{
return pj_mutex_create(pool, name, PJ_MUTEX_RECURSE, mutex);
}
/*
* pj_mutex_lock()
*/
PJ_DEF(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex)
{
pj_status_t status;
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
PJ_LOG(6,(mutex->obj_name, "Mutex: thread %s is waiting",
pj_thread_this()->obj_name));
#if PJ_WIN32_WINNT >= 0x0400
EnterCriticalSection(&mutex->crit);
status=PJ_SUCCESS;
#else
if (WaitForSingleObject(mutex->hMutex, INFINITE)==WAIT_OBJECT_0)
status = PJ_SUCCESS;
else
status = PJ_STATUS_FROM_OS(GetLastError());
#endif
PJ_LOG(6,(mutex->obj_name,
(status==PJ_SUCCESS ? "Mutex acquired by thread %s" : "FAILED by %s"),
pj_thread_this()->obj_name));
#if PJ_DEBUG
if (status == PJ_SUCCESS) {
mutex->owner = pj_thread_this();
++mutex->nesting_level;
}
#endif
return status;
}
/*
* pj_mutex_unlock()
*/
PJ_DEF(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex)
{
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;
}
#endif
PJ_LOG(6,(mutex->obj_name, "Mutex released by thread %s",
pj_thread_this()->obj_name));
#if PJ_WIN32_WINNT >= 0x0400
LeaveCriticalSection(&mutex->crit);
status=PJ_SUCCESS;
#else
status = ReleaseMutex(mutex->hMutex) ? PJ_SUCCESS :
PJ_STATUS_FROM_OS(GetLastError());
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -