template SafeQueue::SafeQueue(size_t maxlen) :writePtr(0), readPtr(0), bufSize(maxlen) { sem_init(&w_space, PTHREAD_PROCESS_PRIVATE, maxlen - 1); sem_init(&r_space, PTHREAD_PROCESS_PRIVATE, 0); buffer = new T[maxlen]; } template SafeQueue::~SafeQueue() { sem_destroy(&w_space); sem_destroy(&r_space); delete [] buffer; } template unsigned int SafeQueue::size() const { return rSpace(); } template unsigned int SafeQueue::rSpace() const { int space = 0; sem_getvalue(&r_space, &space); return space; } template unsigned int SafeQueue::wSpace() const { int space = 0; sem_getvalue(&w_space, &space); return space; } template int SafeQueue::push(const T &in) { if(!wSpace()) return -1; //ok, there is space to write size_t w = (writePtr + 1) % bufSize; buffer[w] = in; writePtr = w; //adjust ranges sem_wait(&w_space); //guaranteed not to wait sem_post(&r_space); return 0; } template int SafeQueue::pop(T &out) { if(!rSpace()) return -1; //ok, there is space to read size_t r = (readPtr + 1) % bufSize; out = buffer[r]; readPtr = r; //adjust ranges sem_wait(&r_space); //guaranteed not to wait sem_post(&w_space); return 0; } template void SafeQueue::clear() { //thread unsafe while(!sem_trywait(&r_space)) sem_post(&w_space); readPtr = writePtr; }