laforge
/
openbts-osmo
Archived
1
0
Fork 0

Better documentation and error reporting for ThreadSemaphore.

This commit is contained in:
Alexander Chemeris 2010-09-09 18:00:49 +04:00 committed by Thomas Tsou
parent 971b6ba700
commit 57d292d962
2 changed files with 93 additions and 15 deletions

View File

@ -28,6 +28,7 @@
#include "Threads.h" #include "Threads.h"
#include "Timeval.h" #include "Timeval.h"
#include <errno.h>
using namespace std; using namespace std;
@ -96,14 +97,66 @@ void Signal::wait(Mutex& wMutex, unsigned timeout) const
pthread_cond_timedwait(&mSignal,&wMutex.mMutex,&waitTime); pthread_cond_timedwait(&mSignal,&wMutex.mMutex,&waitTime);
} }
/** Wait for semaphore to be signaled with timeout. ThreadSemaphore::Result ThreadSemaphore::wait(unsigned timeoutMs)
* @returns 0 on success, -1 on error or timeout.
*/
int ThreadSemaphore::wait(unsigned timeout) const
{ {
Timeval then(timeout); Timeval then(timeoutMs);
struct timespec waitTime = then.timespec(); struct timespec waitTime = then.timespec();
return sem_timedwait(&mSem,&waitTime); int s;
while ((s = sem_timedwait(&mSem,&waitTime)) == -1 && errno == EINTR)
continue;
if (s == -1)
{
if (errno == ETIMEDOUT)
{
return TSEM_TIMEOUT;
}
return TSEM_ERROR;
}
return TSEM_OK;
}
ThreadSemaphore::Result ThreadSemaphore::wait()
{
int s;
while ((s = sem_wait(&mSem)) == -1 && errno == EINTR)
continue;
if (s == -1)
{
return TSEM_ERROR;
}
return TSEM_OK;
}
ThreadSemaphore::Result ThreadSemaphore::trywait()
{
int s;
while ((s = sem_trywait(&mSem)) == -1 && errno == EINTR)
continue;
if (s == -1)
{
if (errno == EAGAIN)
{
return TSEM_TIMEOUT;
}
return TSEM_ERROR;
}
return TSEM_OK;
}
ThreadSemaphore::Result ThreadSemaphore::post()
{
if (sem_post(&mSem) != 0)
{
if (errno == EOVERFLOW)
{
return TSEM_OVERFLOW;
}
return TSEM_ERROR;
}
return TSEM_OK;
} }
void Thread::start(void *(*task)(void*), void *arg) void Thread::start(void *(*task)(void*), void *arg)

View File

@ -126,30 +126,55 @@ class ThreadSemaphore {
private: private:
mutable sem_t mSem; sem_t mSem;
public: public:
ThreadSemaphore(int pshared = 0, unsigned value = 0) { assert(sem_init(&mSem,pshared,value)!=-1); } enum Result {
TSEM_OK, ///< Success.
TSEM_TIMEOUT, ///< wait() or trywait() timed out.
TSEM_OVERFLOW, ///< post() overflows a semaphore
TSEM_ERROR ///< Generic error.
};
/** Create and initialize semaphore.
* @param[in] value - initial semaphore value.
*/
ThreadSemaphore(unsigned value = 0)
{
int s = sem_init(&mSem,0,value);
assert(s == 0);
}
~ThreadSemaphore() { sem_destroy(&mSem); } ~ThreadSemaphore() { sem_destroy(&mSem); }
/** Wait for semaphore to be signaled with timeout. /** Wait for semaphore to be signaled with timeout.
* @returns 0 on success, -1 on error or timeout. * @param[in] timeoutMs - timeout in milliseconds
*
* @retval TSEM_OK on success.
* @retval TSEM_TIMEOUT on timeout.
* @retval TSEM_ERROR on error.
*/ */
int wait (unsigned timeout) const; Result wait(unsigned timeoutMs);
/** Wait for semaphore to be signaled infinitely. /** Wait for semaphore to be signaled infinitely.
* @returns 0 on success, -1 on error. * @retval TSEM_OK on success.
* @retval TSEM_ERROR on error.
*/ */
int wait() const { return sem_wait(&mSem); } Result wait();
/** Check if semaphore has been signaled and disarm it. /** Check if semaphore has been signaled and disarm it.
* @returns 0 if semaphore has been signaled, -1 in other cases. * @retval TSEM_OK is semaphore is signaled.
* @retval TSEM_TIMEOUT if semaphore is not signaled.
* @retval TSEM_ERROR on error.
*/ */
int trywait() const { return sem_trywait(&mSem); } Result trywait();
int post() { return sem_post (&mSem); } /** Signal semaphore.
* @retval TSEM_OK on success.
* @retval TSEM_ERROR on error.
*/
Result post();
}; };