📄 osbtrdpthreads.cpp
字号:
// construct thread attribute pthread_attr_t thread_attr; int prc = pthread_attr_init(&thread_attr); if (prc != 0) { VXItrdThreadDestroyHandle(&result); return VXItrd_RESULT_NON_FATAL_ERROR; } // configure thread attribute#ifdef USE_DETACHED_THREADS prc = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); if (prc != 0) { pthread_attr_destroy(&thread_attr); VXItrdThreadDestroyHandle(&result); return VXItrd_RESULT_NON_FATAL_ERROR; }#else // use joinable threads // this is default - no work required#endif // Start the thread using our wrapper function result->refCount++; // for child prc = pthread_create(&result->thread, &thread_attr, VXItrdThreadStart, (VXItrdThreadArg) result); pthread_attr_destroy(&thread_attr); if (prc != 0) { result->refCount--; VXItrdThreadDestroyHandle(&result); return VXItrd_RESULT_NON_FATAL_ERROR; } *thread = result; return VXItrd_RESULT_SUCCESS;}/** * Destroy a thread handle * * Note: this does NOT stop or destroy the thread, it just releases * the handle for accessing it. If this is not done, a memory leak * occurs, so if the creator of the thread never needs to communicate * with the thread again it should call this immediately after the * create if the create was successful. * * @param thread Handle to the thread to destroy * * @result VXItrdResult 0 on success */VXITRD_API VXItrdResult VXItrdThreadDestroyHandle(VXItrdThread **thread){ if ((thread == NULL) || (*thread == NULL)) return VXItrd_RESULT_INVALID_ARGUMENT; // Decrement ref count VXIulong refs = 0; if ((*thread)->refCountMutex) { VXItrdMutexLock ((*thread)->refCountMutex); (*thread)->refCount--; refs = (*thread)->refCount; VXItrdMutexUnlock ((*thread)->refCountMutex); } if (refs == 0) { // No longer needed if ((*thread)->refCountMutex) VXItrdMutexDestroy (&(*thread)->refCountMutex); delete *thread; } *thread = NULL; return VXItrd_RESULT_SUCCESS;}/** * Terminate a thread. Called by the thread on exit. * * @param status Exit code for the thread * @result N/A, never returns */VXITRD_API void VXItrdThreadExit(VXItrdThreadArg status){ pthread_exit(status);}/** * Causes the calling thread to wait for the termination of a specified * 'thread' with a specified timeout, in milliseconds. * * @param thread the 'thread' that is waited for its termination. * @param status contains the exit value of the thread's start routine. * @return VXItrdResult of operation. Return SUCCESS if specified 'thread' * terminating. */VXITRD_API VXItrdResult VXItrdThreadJoin(VXItrdThread *thread, VXItrdThreadArg *status, long timeout){ if ((thread == NULL ) || (status == NULL) || (timeout < -1)) return VXItrd_RESULT_INVALID_ARGUMENT; VXItrdResult rc = VXItrd_RESULT_SUCCESS; if (timeout == -1) { // Wait forever if (pthread_join(thread->thread, status) != 0) rc = VXItrd_RESULT_SYSTEM_ERROR; } else { // Wait with a timeout, we just do a polling implementation long remainingMsec = timeout; while ((remainingMsec > 0) && (thread->state != STATE_EXITED) && (rc == VXItrd_RESULT_SUCCESS)) { if (remainingMsec > 50) { rc = VXItrdSleep (50); remainingMsec -= 50; } else { rc = VXItrdSleep (remainingMsec); remainingMsec = 0; } } if (rc == VXItrd_RESULT_SUCCESS) { if (thread->state == STATE_EXITED) { // Collect the thread if (pthread_join(thread->thread, status) != 0) rc = VXItrd_RESULT_SYSTEM_ERROR; } else { rc = VXItrd_RESULT_FAILURE; } } } return rc;}/** * Get the thread ID for the specified thread * * @param thread Handle to the thread to get the ID for * * @result Thread ID number */VXITRD_API VXIlong VXItrdThreadGetIDFromHandle(VXItrdThread *thread){ if (thread == NULL) return -1; return thread->thread;}/** * Get the ID of the current handle. * * @return The current thread handle identifier. * */VXITRD_API VXIlong VXItrdThreadGetID(void){ return (VXIlong)pthread_self(); }/** * Purpose Yield the process schedule in the current thread. * * @return void * */VXITRD_API void VXItrdThreadYield(void){ sched_yield();}/** * Create a timer * * @param timer a pointer to a timer * @return VXItrdResult of operation. Return SUCCESS if timer has been * created * */VXITRD_API VXItrdResult VXItrdTimerCreate(VXItrdTimer **timer){ if (timer == NULL) return VXItrd_RESULT_INVALID_ARGUMENT; VXItrdTimer *result = new VXItrdTimer; if (result == NULL) return VXItrd_RESULT_OUT_OF_MEMORY; // Initialize all data result->isSleeping = FALSE; result->wakeUp = FALSE; *timer = result; return VXItrd_RESULT_SUCCESS;}/** * Destroy a timer * * @param timer a pointer to a timer * @return VXItrdResult of operation. Return SUCCESS if timer has been * created * */VXITRD_API VXItrdResult VXItrdTimerDestroy(VXItrdTimer **timer){ if ((timer == NULL) || (*timer == NULL)) return VXItrd_RESULT_INVALID_ARGUMENT; // Don't leave the corresponding thread in a suspended state. VXItrdResult rc = VXItrd_RESULT_SUCCESS; if ((*timer)->isSleeping) { VXItrdTimerWake(*timer); // Wait for the sleeping thread to wake up, note that on some OSes // like Linux the timeout is modified to give the actual amount of // time slept so need to re-initialize each time while (((*timer)->isSleeping) && ((rc = VXItrdSleep (50)) == VXItrd_RESULT_SUCCESS)) ; // keep going } delete *timer; *timer = NULL; return rc;}/** * Puts the current thread to sleep for a configurable duration. * Due to other activities of the machine, the delay is the minimum * length that the timer will wait. * * @param timer a pointer to a timer * @param millisecondDelay the minimum number of milliseconds to wait * @param interrupted a pointer (may optionally be NULL) indicating whether * or not the sleep was interrupted by VXItrdTimerWake. * @return VXItrdResult of operation. Return SUCCESS if timer could sleep. * */VXITRD_API VXItrdResult VXItrdTimerSleep(VXItrdTimer *timer, VXIint millisecondDelay, VXIbool *interrupted){ if ((timer == NULL) || (millisecondDelay < 0)) return VXItrd_RESULT_INVALID_ARGUMENT; if (timer->isSleeping == TRUE) return VXItrd_RESULT_FATAL_ERROR; // Sleep, we just do a polling implementation VXItrdResult rc = VXItrd_RESULT_SUCCESS; VXIint remainingMsec = millisecondDelay; timer->isSleeping = TRUE; while ((remainingMsec > 0) && (timer->wakeUp == FALSE) && (rc == VXItrd_RESULT_SUCCESS)) { if (remainingMsec > 50) { rc = VXItrdSleep (50); remainingMsec -= 50; } else { rc = VXItrdSleep (remainingMsec); remainingMsec = 0; } } if (interrupted) *interrupted = (timer->wakeUp ? TRUE : FALSE); timer->wakeUp = FALSE; timer->isSleeping = FALSE; return VXItrd_RESULT_SUCCESS;}/** * Wakes a sleeping thread, if the target is not already sleeping * it immediately wakes when it tries to sleep the next time. * * @param timer a pointer to a timer * @return VXItrdResult of operation. Return SUCCESS if timer could wake. * */VXITRD_API VXItrdResult VXItrdTimerWake(VXItrdTimer *timer){ if (timer == NULL) return VXItrd_RESULT_INVALID_ARGUMENT; timer->wakeUp = TRUE; return VXItrd_RESULT_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -