ptimedsem.cxx (2111B)
1 /* 2 * 3 * C++ Portable Types Library (PTypes) 4 * Version 2.1.1 Released 27-Jun-2007 5 * 6 * Copyright (C) 2001-2007 Hovik Melikyan 7 * 8 * http://www.melikyan.com/ptypes/ 9 * 10 */ 11 12 #ifdef WIN32 13 # include <windows.h> 14 #else 15 # include <sys/time.h> 16 # include <pthread.h> 17 # include <errno.h> 18 #endif 19 20 #include "pasync.h" 21 22 23 namespace ptypes { 24 25 26 static void tsem_fail() 27 { 28 fatal(CRIT_FIRST + 41, "Timed semaphore failed"); 29 } 30 31 32 #ifdef WIN32 33 34 35 timedsem::timedsem(int initvalue) 36 { 37 handle = CreateSemaphore(nil, initvalue, 65535, nil); 38 if (handle == 0) 39 tsem_fail(); 40 } 41 42 43 timedsem::~timedsem() 44 { 45 CloseHandle(handle); 46 } 47 48 49 bool timedsem::wait(int timeout) 50 { 51 uint r = WaitForSingleObject(handle, timeout); 52 if (r == WAIT_FAILED) 53 tsem_fail(); 54 return r != WAIT_TIMEOUT; 55 } 56 57 58 void timedsem::post() 59 { 60 if (ReleaseSemaphore(handle, 1, nil) == 0) 61 tsem_fail(); 62 } 63 64 65 #else 66 67 68 inline void tsem_syscheck(int r) 69 { 70 if (r != 0) 71 tsem_fail(); 72 } 73 74 75 timedsem::timedsem(int initvalue) 76 : unknown(), count(initvalue) 77 { 78 tsem_syscheck(pthread_mutex_init(&mtx, 0)); 79 tsem_syscheck(pthread_cond_init(&cond, 0)); 80 } 81 82 83 timedsem::~timedsem() 84 { 85 pthread_cond_destroy(&cond); 86 pthread_mutex_destroy(&mtx); 87 } 88 89 90 bool timedsem::wait(int timeout) 91 { 92 pthread_mutex_lock(&mtx); 93 while (count <= 0) 94 { 95 if (timeout >= 0) 96 { 97 timespec abs_ts; 98 timeval cur_tv; 99 gettimeofday(&cur_tv, NULL); 100 abs_ts.tv_sec = cur_tv.tv_sec + timeout / 1000; 101 abs_ts.tv_nsec = cur_tv.tv_usec * 1000 102 + (timeout % 1000) * 1000000; 103 int rc = pthread_cond_timedwait(&cond, &mtx, &abs_ts); 104 if (rc == ETIMEDOUT) { 105 pthread_mutex_unlock(&mtx); 106 return false; 107 } 108 } 109 else 110 pthread_cond_wait(&cond, &mtx); 111 } 112 count--; 113 pthread_mutex_unlock(&mtx); 114 return true; 115 } 116 117 118 void timedsem::post() 119 { 120 pthread_mutex_lock(&mtx); 121 count++; 122 pthread_cond_signal(&cond); 123 pthread_mutex_unlock(&mtx); 124 } 125 126 127 #endif 128 129 130 }