📄 os_core_win32.c
字号:
return status;
}
/*
* pj_mutex_trylock()
*/
PJ_DEF(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex)
{
pj_status_t status;
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
#if PJ_WIN32_WINNT >= 0x0400
status=TryEnterCriticalSection(&mutex->crit) ? PJ_SUCCESS : PJ_EUNKNOWN;
#else
status = WaitForSingleObject(mutex->hMutex, 0)==WAIT_OBJECT_0 ?
PJ_SUCCESS : PJ_ETIMEDOUT;
#endif
if (status==PJ_SUCCESS) {
PJ_LOG(6,(mutex->obj_name, "Mutex acquired by thread %s",
pj_thread_this()->obj_name));
#if PJ_DEBUG
mutex->owner = pj_thread_this();
++mutex->nesting_level;
#endif
}
return status;
}
/*
* pj_mutex_destroy()
*/
PJ_DEF(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex)
{
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
PJ_LOG(6,(mutex->obj_name, "Mutex destroyed"));
#if PJ_WIN32_WINNT >= 0x0400
DeleteCriticalSection(&mutex->crit);
return PJ_SUCCESS;
#else
return CloseHandle(mutex->hMutex) ? PJ_SUCCESS :
PJ_RETURN_OS_ERROR(GetLastError());
#endif
}
#if PJ_DEBUG
/*
* pj_mutex_is_locked()
*/
PJ_DEF(pj_bool_t) pj_mutex_is_locked(pj_mutex_t *mutex)
{
return mutex->owner == pj_thread_this();
}
#endif
///////////////////////////////////////////////////////////////////////////////
/*
* Win32 lacks Read/Write mutex, so include the emulation.
*/
#include "os_rwmutex.c"
///////////////////////////////////////////////////////////////////////////////
/*
* pj_enter_critical_section()
*/
PJ_DEF(void) pj_enter_critical_section(void)
{
pj_mutex_lock(&critical_section_mutex);
}
/*
* pj_leave_critical_section()
*/
PJ_DEF(void) pj_leave_critical_section(void)
{
pj_mutex_unlock(&critical_section_mutex);
}
///////////////////////////////////////////////////////////////////////////////
#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 **sem_ptr)
{
pj_sem_t *sem;
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(pool && sem_ptr, PJ_EINVAL);
sem = pj_pool_alloc(pool, sizeof(*sem));
sem->hSemaphore = CreateSemaphore(NULL, initial, max, NULL);
if (!sem->hSemaphore)
return PJ_RETURN_OS_ERROR(GetLastError());
/* Set name. */
if (!name) {
name = "sem%p";
}
if (strchr(name, '%')) {
pj_ansi_snprintf(sem->obj_name, PJ_MAX_OBJ_NAME, name, sem);
} else {
pj_ansi_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"));
*sem_ptr = sem;
return PJ_SUCCESS;
}
static pj_status_t pj_sem_wait_for(pj_sem_t *sem, unsigned timeout)
{
DWORD 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 = WaitForSingleObject(sem->hSemaphore, timeout);
if (result == WAIT_OBJECT_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==WAIT_OBJECT_0)
return PJ_SUCCESS;
else if (result==WAIT_TIMEOUT)
return PJ_ETIMEDOUT;
else
return PJ_RETURN_OS_ERROR(GetLastError());
}
/*
* pj_sem_wait()
*/
PJ_DEF(pj_status_t) pj_sem_wait(pj_sem_t *sem)
{
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(sem, PJ_EINVAL);
return pj_sem_wait_for(sem, INFINITE);
}
/*
* pj_sem_trywait()
*/
PJ_DEF(pj_status_t) pj_sem_trywait(pj_sem_t *sem)
{
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(sem, PJ_EINVAL);
return pj_sem_wait_for(sem, 0);
}
/*
* pj_sem_post()
*/
PJ_DEF(pj_status_t) pj_sem_post(pj_sem_t *sem)
{
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(sem, PJ_EINVAL);
PJ_LOG(6, (sem->obj_name, "Semaphore released by thread %s",
pj_thread_this()->obj_name));
if (ReleaseSemaphore(sem->hSemaphore, 1, NULL))
return PJ_SUCCESS;
else
return PJ_RETURN_OS_ERROR(GetLastError());
}
/*
* pj_sem_destroy()
*/
PJ_DEF(pj_status_t) pj_sem_destroy(pj_sem_t *sem)
{
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));
if (CloseHandle(sem->hSemaphore))
return PJ_SUCCESS;
else
return PJ_RETURN_OS_ERROR(GetLastError());
}
#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 **event_ptr)
{
pj_event_t *event;
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(pool && event_ptr, PJ_EINVAL);
event = pj_pool_alloc(pool, sizeof(*event));
if (!event)
return PJ_ENOMEM;
event->hEvent = CreateEvent(NULL, manual_reset?TRUE:FALSE,
initial?TRUE:FALSE, NULL);
if (!event->hEvent)
return PJ_RETURN_OS_ERROR(GetLastError());
/* Set name. */
if (!name) {
name = "evt%p";
}
if (strchr(name, '%')) {
pj_ansi_snprintf(event->obj_name, PJ_MAX_OBJ_NAME, name, event);
} else {
pj_ansi_strncpy(event->obj_name, name, PJ_MAX_OBJ_NAME);
event->obj_name[PJ_MAX_OBJ_NAME-1] = '\0';
}
PJ_LOG(6, (event->obj_name, "Event created"));
*event_ptr = event;
return PJ_SUCCESS;
}
static pj_status_t pj_event_wait_for(pj_event_t *event, unsigned timeout)
{
DWORD result;
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(event, PJ_EINVAL);
PJ_LOG(6, (event->obj_name, "Event: thread %s is waiting",
pj_thread_this()->obj_name));
result = WaitForSingleObject(event->hEvent, timeout);
if (result == WAIT_OBJECT_0) {
PJ_LOG(6, (event->obj_name, "Event: thread %s is released",
pj_thread_this()->obj_name));
} else {
PJ_LOG(6, (event->obj_name, "Event: thread %s FAILED to acquire",
pj_thread_this()->obj_name));
}
if (result==WAIT_OBJECT_0)
return PJ_SUCCESS;
else if (result==WAIT_TIMEOUT)
return PJ_ETIMEDOUT;
else
return PJ_RETURN_OS_ERROR(GetLastError());
}
/*
* pj_event_wait()
*/
PJ_DEF(pj_status_t) pj_event_wait(pj_event_t *event)
{
PJ_ASSERT_RETURN(event, PJ_EINVAL);
return pj_event_wait_for(event, INFINITE);
}
/*
* pj_event_trywait()
*/
PJ_DEF(pj_status_t) pj_event_trywait(pj_event_t *event)
{
PJ_ASSERT_RETURN(event, PJ_EINVAL);
return pj_event_wait_for(event, 0);
}
/*
* pj_event_set()
*/
PJ_DEF(pj_status_t) pj_event_set(pj_event_t *event)
{
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(event, PJ_EINVAL);
PJ_LOG(6, (event->obj_name, "Setting event"));
if (SetEvent(event->hEvent))
return PJ_SUCCESS;
else
return PJ_RETURN_OS_ERROR(GetLastError());
}
/*
* pj_event_pulse()
*/
PJ_DEF(pj_status_t) pj_event_pulse(pj_event_t *event)
{
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(event, PJ_EINVAL);
PJ_LOG(6, (event->obj_name, "Pulsing event"));
if (PulseEvent(event->hEvent))
return PJ_SUCCESS;
else
return PJ_RETURN_OS_ERROR(GetLastError());
}
/*
* pj_event_reset()
*/
PJ_DEF(pj_status_t) pj_event_reset(pj_event_t *event)
{
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(event, PJ_EINVAL);
PJ_LOG(6, (event->obj_name, "Event is reset"));
if (ResetEvent(event->hEvent))
return PJ_SUCCESS;
else
return PJ_RETURN_OS_ERROR(GetLastError());
}
/*
* pj_event_destroy()
*/
PJ_DEF(pj_status_t) pj_event_destroy(pj_event_t *event)
{
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(event, PJ_EINVAL);
PJ_LOG(6, (event->obj_name, "Event is destroying"));
if (CloseHandle(event->hEvent))
return PJ_SUCCESS;
else
return PJ_RETURN_OS_ERROR(GetLastError());
}
#endif /* PJ_HAS_EVENT_OBJ */
///////////////////////////////////////////////////////////////////////////////
#if defined(PJ_TERM_HAS_COLOR) && PJ_TERM_HAS_COLOR != 0
/*
* Terminal color
*/
static WORD pj_color_to_os_attr(pj_color_t color)
{
WORD attr = 0;
if (color & PJ_TERM_COLOR_R)
attr |= FOREGROUND_RED;
if (color & PJ_TERM_COLOR_G)
attr |= FOREGROUND_GREEN;
if (color & PJ_TERM_COLOR_B)
attr |= FOREGROUND_BLUE;
if (color & PJ_TERM_COLOR_BRIGHT)
attr |= FOREGROUND_INTENSITY;
return attr;
}
static pj_color_t os_attr_to_pj_color(WORD attr)
{
int color = 0;
if (attr & FOREGROUND_RED)
color |= PJ_TERM_COLOR_R;
if (attr & FOREGROUND_GREEN)
color |= PJ_TERM_COLOR_G;
if (attr & FOREGROUND_BLUE)
color |= PJ_TERM_COLOR_B;
if (attr & FOREGROUND_INTENSITY)
color |= PJ_TERM_COLOR_BRIGHT;
return color;
}
/*
* pj_term_set_color()
*/
PJ_DEF(pj_status_t) pj_term_set_color(pj_color_t color)
{
BOOL rc;
WORD attr = 0;
PJ_CHECK_STACK();
attr = pj_color_to_os_attr(color);
rc = SetConsoleTextAttribute( GetStdHandle(STD_OUTPUT_HANDLE), attr);
return rc ? PJ_SUCCESS : PJ_RETURN_OS_ERROR(GetLastError());
}
/*
* pj_term_get_color()
* Get current terminal foreground color.
*/
PJ_DEF(pj_color_t) pj_term_get_color(void)
{
CONSOLE_SCREEN_BUFFER_INFO info;
PJ_CHECK_STACK();
GetConsoleScreenBufferInfo( GetStdHandle(STD_OUTPUT_HANDLE), &info);
return os_attr_to_pj_color(info.wAttributes);
}
#endif /* PJ_TERM_HAS_COLOR */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -