📄 sbtrd.cpp
字号:
/****************License************************************************
*
* Copyright 2000-2003. ScanSoft, Inc.
*
* Use of this software is subject to notices and obligations set forth
* in the SpeechWorks Public License - Software Version 1.2 which is
* included with this software.
*
* ScanSoft is a registered trademark of ScanSoft, Inc., and OpenSpeech,
* SpeechWorks and the SpeechWorks logo are registered trademarks or
* trademarks of SpeechWorks International, Inc. in the United States
* and other countries.
*
***********************************************************************/
/*****************************************************************************
*****************************************************************************
*
* SBtrd API implementation
*
* This provides the Win32 implementation of the VXItrd API for basic
* thread operations and locks. Unlike most of the other VXI APIs,
* this is implemented in a library (on Windows a DLL with a specific
* name, on other operating systems as a static, shared, or dynamic
* library). Implementations of this API are operating system
* dependant.
*
* To avoid cyclic dependancies, this does not perform logging. Clients
* must do error logging themselves based on passed return codes.
*
*****************************************************************************
*****************************************************************************/
// -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8
#include <vxibuildopts.h>
#if P_VXI
#ifndef WIN32
#error This file is intended only for use with the Microsoft Windows API.
#endif
#include <stdlib.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <process.h>
#define VXITRD_EXPORTS
#include "vxi/VXItrd.h" // Header for this API
#if ( ! defined(NDEBUG) ) && ( ! defined(VXITRD_RECURSIVE_MUTEX) )
#include <assert.h>
/* Suppress/disable warnings triggered by asserts below */
#pragma warning(4 : 4130) /* logical operation on address of string constant */
#endif
extern "C" struct VXItrdMutex {
#ifdef VXITRD_KERNEL_MUTEX
HANDLE mutex;
#else
CRITICAL_SECTION critSection;
#endif
#if ( ! defined(NDEBUG) ) && ( ! defined(VXITRD_RECURSIVE_MUTEX) )
volatile bool locked;
#endif
};
extern "C" struct VXItrdThread {
HANDLE threadHandle;
unsigned int threadID;
};
extern "C" struct VXItrdTimer {
HANDLE timerEvent;
};
static VXIint32 g_threadStackSize = 0;
// -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8
/**
* Creates a new mutex initialized to the unlocked state. If the calling
* thread terminates, the created mutex is not automatically deallocated as
* it may be shared among multiple threads.
*
* @return Fatal error (ex: system lacks necessary resources for creation)
* Success; valid mutex has been created
*/
VXITRD_API VXItrdResult VXItrdMutexCreate(VXItrdMutex **mutex)
{
VXItrdResult rc = VXItrd_RESULT_SUCCESS;
if (mutex == NULL) return VXItrd_RESULT_INVALID_ARGUMENT;
*mutex = NULL;
// Create the wrapper object
VXItrdMutex *result = new VXItrdMutex;
if (result == NULL)
return VXItrd_RESULT_OUT_OF_MEMORY;
#if ( ! defined(NDEBUG) ) && ( ! defined(VXITRD_RECURSIVE_MUTEX) )
result->locked = false;
#endif
// Create the critical section or mutex, use Win32 exception
// handling to catch predicatable problems
__try {
#ifdef VXITRD_KERNEL_MUTEX
result->mutex = CreateMutex(NULL, FALSE, NULL);
if (result->mutex == NULL)
rc = VXItrd_RESULT_SYSTEM_ERROR;
#else
InitializeCriticalSection(&result->critSection);
#endif
}
__except (GetExceptionCode() == STATUS_NO_MEMORY ?
EXCEPTION_EXECUTE_HANDLER :
EXCEPTION_CONTINUE_SEARCH ) {
rc = VXItrd_RESULT_OUT_OF_MEMORY;
}
if (rc == VXItrd_RESULT_SUCCESS)
*mutex = result;
else if (result)
delete result;
return rc;
}
/**
* Deletes an existing mutex. It is illegal to delete a locked mutex.
*
* @return Fatal error (ex: invalid mutex)
* Success; mutex has been destroyed
* Mutex is locked
*/
VXITRD_API VXItrdResult VXItrdMutexDestroy(VXItrdMutex **mutex)
{
VXItrdResult rc = VXItrd_RESULT_SUCCESS;
if ((! mutex) || (! *mutex)) return VXItrd_RESULT_INVALID_ARGUMENT;
#if ( ! defined(NDEBUG) ) && ( ! defined(VXITRD_RECURSIVE_MUTEX) )
// Check the lock state
if ( (*mutex)->locked ) {
assert ("VXItrdMutexDestroy( ) on locked mutex" );
return VXItrd_RESULT_FATAL_ERROR;
}
#endif
// Are no predictable problems, so no Win32 exception handling
#ifdef VXITRD_KERNEL_MUTEX
if (CloseHandle((*mutex)->mutex) == FALSE)
rc = VXItrd_RESULT_SYSTEM_ERROR;
#else
DeleteCriticalSection(&(*mutex)->critSection);
#endif
delete *mutex;
*mutex = NULL;
return rc;
}
/**
* Locks an existing mutex. If the mutex is already locked, the thread waits
* for the mutex to become available.
*
* @return: Fatal error (ex: invalid mutex or deadlock detected)
* Success; mutex is now locked
* Mutex already locked by current thread.
*/
VXITRD_API VXItrdResult VXItrdMutexLock(VXItrdMutex *mutex)
{
if (mutex == NULL) return VXItrd_RESULT_INVALID_ARGUMENT;
__try {
#ifdef VXITRD_KERNEL_MUTEX
int result = WaitForSingleObject(mutex->mutex, INFINITE);
if (result == WAIT_FAILED)
return VXItrd_RESULT_SYSTEM_ERROR;
#else
EnterCriticalSection(&mutex->critSection);
#endif
}
__except (GetExceptionCode() == STATUS_INVALID_HANDLE ?
EXCEPTION_EXECUTE_HANDLER :
EXCEPTION_CONTINUE_SEARCH ) {
// Yes, Microsoft says STATUS_INVALID_HANDLE is returned on low memory
return VXItrd_RESULT_OUT_OF_MEMORY;
}
#if ( ! defined(NDEBUG) ) && ( ! defined(VXITRD_RECURSIVE_MUTEX) )
// Check the lock state
if ( mutex->locked ) {
// Should not be locking the same mutex twice, very OS dependant
// (Win32 says the behavior is undefined) and not gauranteed by
// VXItrdMutex
assert ("VXItrdMutexLock( ) on already locked mutex" );
return VXItrd_RESULT_FATAL_ERROR;
} else {
mutex->locked = true;
}
#endif
return VXItrd_RESULT_SUCCESS;
}
/**
* Unlocks a mutex owned by the thread.
*
* @return: Fatal error (ex: invalid mutex)
* Success; mutex no longer owned by calling thread
* Mutex not owned by thread.
*/
VXITRD_API VXItrdResult VXItrdMutexUnlock(VXItrdMutex *mutex)
{
if (mutex == NULL) return VXItrd_RESULT_INVALID_ARGUMENT;
#if ( ! defined(NDEBUG) ) && ( ! defined(VXITRD_RECURSIVE_MUTEX) )
// Check the lock state
if ( ! mutex->locked ) {
// Unlocking a mutex that wasn't locked
assert ("VXItrdMutexUnlock( ) on unlocked mutex");
return VXItrd_RESULT_FATAL_ERROR;
} else {
mutex->locked = false;
}
#endif
#ifdef VXITRD_KERNEL_MUTEX
int result = ReleaseMutex(mutex->mutex);
if (result == FALSE)
return VXItrd_RESULT_FATAL_ERROR;
#else
LeaveCriticalSection(&mutex->critSection);
#endif
return VXItrd_RESULT_SUCCESS;
}
/**
* Purpose Create a thread. Note thread values are not supported on OS/2.
* execution starts on the thread immediately. To pause execution
* use a Mutex between the thread and the thread creator.
*
* @param thread the thread object to be created
* @param start_func the function for the thread to start execution on
* @param arg the arguments to the thread function
* @return VXItrdResult of operation. Return SUCCESS if thread has been
* created and started.
*
*/
VXITRD_API
VXItrdResult VXItrdThreadCreate(VXItrdThread **thread,
VXItrdThreadStartFunc thread_function,
VXItrdThreadArg thread_arg)
{
if ((thread == NULL) || (thread_function == NULL))
return VXItrd_RESULT_INVALID_ARGUMENT;
*thread = NULL;
// Create the wrapper object
VXItrdThread *result = new VXItrdThread;
if (result == NULL)
return VXItrd_RESULT_OUT_OF_MEMORY;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -