laforge
/
openbts-osmo
Archived
1
0
Fork 0

Better documentation and error reporting for ThreadSemaphore.

master
Alexander Chemeris 12 years ago committed by Thomas Tsou
parent 971b6ba700
commit 57d292d962
  1. 65
      public-trunk/CommonLibs/Threads.cpp
  2. 43
      public-trunk/CommonLibs/Threads.h

@ -28,6 +28,7 @@
#include "Threads.h"
#include "Timeval.h"
#include <errno.h>
using namespace std;
@ -96,14 +97,66 @@ void Signal::wait(Mutex& wMutex, unsigned timeout) const
pthread_cond_timedwait(&mSignal,&wMutex.mMutex,&waitTime);
}
/** Wait for semaphore to be signaled with timeout.
* @returns 0 on success, -1 on error or timeout.
*/
int ThreadSemaphore::wait(unsigned timeout) const
ThreadSemaphore::Result ThreadSemaphore::wait(unsigned timeoutMs)
{
Timeval then(timeout);
Timeval then(timeoutMs);
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)

@ -126,30 +126,55 @@ class ThreadSemaphore {
private:
mutable sem_t mSem;
sem_t mSem;
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); }
/** 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.
* @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.
* @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();
};