📄 osbtrdpthreads.cpp
字号:
/***************************************************************************** ***************************************************************************** * * $Id: SBtrdPthreads.cpp,v 1.1.2.3 2001/10/31 16:32:41 dmeyer Exp $ * * SBtrd API implementation * * This provides the Linux 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. * ***************************************************************************** *****************************************************************************//****************License************************************************ * * Copyright 2000-2001. SpeechWorks International, Inc. * * Use of this software is subject to notices and obligations set forth * in the SpeechWorks Public License - Software Version 1.1 which is * included with this software. * * SpeechWorks is a registered trademark, and SpeechWorks Here, * DialogModules and the SpeechWorks logo are trademarks of SpeechWorks * International, Inc. in the United States and other countries. * ************************************************************************ */static const char *rcsid = 0 ? (char *) &rcsid :"$Id: SBtrdPthreads.cpp,v 1.1.2.3 2001/10/31 16:32:41 dmeyer Exp $";// -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8#include <stdio.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include <pthread.h>#include <sys/time.h>#include <sys/types.h>#define VXITRD_EXPORTS#include "VXItrd.h" // Header for this APIextern "C" {struct VXItrdMutex { pthread_mutex_t mutex;};}typedef enum VXItrdThreadState { STATE_STARTING = 0, STATE_RUNNING = 1, STATE_EXITED = 2} VXItrdThreadState;extern "C" {struct VXItrdThread { pthread_t thread; // Thread handle VXItrdThreadState state; // Thread state VXItrdMutex *refCountMutex; // For reference count protection VXIulong refCount; // References to this structure VXItrdThreadStartFunc thread_function; // user's thread function VXItrdThreadArg thread_arg; // user's thread argument};}extern "C" {struct VXItrdTimer { VXIbool isSleeping; /* If 1, thread is currently sleeping */ VXIbool wakeUp; /* If 1, thread will ignore the next Sleep() */};}// -----1=0-------2=0-------3=0-------4=0-------5=0-------6=0-------7=0-------8/** * Internal utility function for sleeping */static VXItrdResult VXItrdSleep(VXIint millisecondDelay){ // Do not want to use usleep( ), non-portable and it is usually implemented // via signals which may mess up other software in the system which is // also trying to use signals. Note that it is very important to set up // the timer each time as on some OSes (like Linux) the timeout var is // modified to indicate the actual time slept. struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = millisecondDelay * 1000; if (select (0, NULL, NULL, NULL, &timeout) < 0) return VXItrd_RESULT_SYSTEM_ERROR; return VXItrd_RESULT_SUCCESS;}/** * 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 -1 Fatal error (ex: system lacks necessary resources for creation) * 0 Success; valid mutex has been created */VXITRD_API VXItrdResult VXItrdMutexCreate(VXItrdMutex **mutex){ 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; // Create the critical section */ int rc; pthread_mutexattr_t mutexattr; // Create and configure mutex attributes for recursive mutex rc = pthread_mutexattr_init(&mutexattr); if (rc != 0) { delete result; return VXItrd_RESULT_NON_FATAL_ERROR; } #ifndef _unixware7_ rc = pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE); if (rc != 0) { pthread_mutexattr_destroy(&mutexattr); delete result; return VXItrd_RESULT_NON_FATAL_ERROR; }#endif // Initialize mutex with RECURSIVE attributes rc = pthread_mutex_init(&result->mutex, &mutexattr); if (rc != 0) { pthread_mutexattr_destroy(&mutexattr); delete result; return VXItrd_RESULT_NON_FATAL_ERROR; } rc = pthread_mutexattr_destroy(&mutexattr); if (rc != 0) { pthread_mutex_destroy(&result->mutex); delete result; return VXItrd_RESULT_NON_FATAL_ERROR; } *mutex = result; return VXItrd_RESULT_SUCCESS;}/** * Deletes an existing mutex. It is illegal to delete a locked mutex. * * @return -1 Fatal error (ex: invalid mutex) * 0 Success; mutex has been destroyed * 1 Mutex is locked */VXITRD_API VXItrdResult VXItrdMutexDestroy(VXItrdMutex **mutex){ if ((mutex == NULL) || (*mutex == NULL)) return VXItrd_RESULT_INVALID_ARGUMENT; int rc; rc = pthread_mutex_destroy(&(*mutex)->mutex); if (rc != 0) { return VXItrd_RESULT_NON_FATAL_ERROR; } delete *mutex; *mutex = NULL; return VXItrd_RESULT_SUCCESS;}/** * Locks an existing mutex. If the mutex is already locked, the thread waits * for the mutex to become available. * * @return: -1 Fatal error (ex: invalid mutex or deadlock detected) * 0 Success; mutex is now locked * 1 Mutex already locked by current thread. */VXITRD_API VXItrdResult VXItrdMutexLock(VXItrdMutex *mutex){ if (mutex == NULL) return VXItrd_RESULT_INVALID_ARGUMENT; int rc; rc = pthread_mutex_lock(&mutex->mutex); if (rc != 0) { return VXItrd_RESULT_NON_FATAL_ERROR; } return VXItrd_RESULT_SUCCESS;}/** * Unlocks a mutex owned by the thread. * * @return: -1 Fatal error (ex: invalid mutex) * 0 Success; mutex no longer owned by calling thread * 1 Mutex not owned by thread. */VXITRD_API VXItrdResult VXItrdMutexUnlock(VXItrdMutex *mutex){ if (mutex == NULL) return VXItrd_RESULT_INVALID_ARGUMENT; int rc; rc = pthread_mutex_unlock(&mutex->mutex); if (rc != 0) { return VXItrd_RESULT_NON_FATAL_ERROR; } return VXItrd_RESULT_SUCCESS;}/** * Internal: wrapper functions for starting/cleaning up threads */static void VXItrdThreadCleanup(VXItrdThreadArg userData){ VXItrdThread *thread = (VXItrdThread *) userData; // No longer active thread->state = STATE_EXITED; // Free our copy of the thread handle VXItrdThreadDestroyHandle (&thread);}static VXITRD_DEFINE_THREAD_FUNC(VXItrdThreadStart, userData){ VXItrdThread *thread = (VXItrdThread *) userData; // Set the state and register a cleanup function to finish it, // required for ThreadJoin( ) support thread->state = STATE_RUNNING; pthread_cleanup_push(VXItrdThreadCleanup, userData); // Call the user function VXItrdThreadArg status = (*thread->thread_function)(thread->thread_arg); // Cleanup, the 1 to pop causes the cleanup function to be invoked pthread_cleanup_pop(1); return NULL; // never gets called, just to eliminate compile warning}/** * 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 thread_function the function for the thread to start execution on * @param thread_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; memset(result, 0, sizeof (VXItrdThread)); result->state = STATE_STARTING; result->refCount = 1; // 1 for parent result->thread_function = thread_function; result->thread_arg = thread_arg; if (VXItrdMutexCreate(&result->refCountMutex) != VXItrd_RESULT_SUCCESS) { VXItrdThreadDestroyHandle(&result); return VXItrd_RESULT_SYSTEM_ERROR; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -