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

📄 os_core_win32.c

📁 一个开源SIP协议栈
💻 C
📖 第 1 页 / 共 3 页
字号:
    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 + -