Better documentation and error reporting for ThreadSemaphore.
parent
971b6ba700
commit
57d292d962
|
@ -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();
|
||||
|
||||
};
|
||||
|
||||
|
|
Reference in New Issue