views:

212

answers:

1

I have a queue with a semaphore. At certain point all the calls to sem_post() always return 'Invalid argument' error although the semaphore itself is valid

The semaphore is a private member of C++ object which is never deleted, it also can be inspected in gdb. I added sem_getvalue() just before the sem_post() - the value reads OK and then it fails on sem_post(). What could be wrong?

CThreadQueue::CThreadQueue(int MaxSize) :
    _MaxSize(MaxSize)
{
    sem_init(&_TaskCount, 0, 0)

    pthread_mutex_init(&_Mutex, 0);
    pthread_create(&_Thread, NULL, CThreadQueue::StartThread, this);
}


CThreadQueue::~CThreadQueue()
{
    pthread_kill(_Thread, SIGKILL);
    sem_destroy(&_TaskCount);
}


int CThreadQueue::AddTask(CThreadTask Task)
{
    pthread_mutex_lock(&_Mutex);
    _Queue.push_back(TempTask);
    sem_post(&_TaskCount)
    pthread_mutex_unlock(&_Mutex);

    return 0;
}

void *CThreadQueue::StartThread(void *Obj)
{
    ((CThreadQueue*)Obj)->RunThread();
    return NULL;
}

//runs in a separate thread
void CThreadQueue::RunThread()
{
    CThreadQueue::CTask Task;

    while(1) {
        sem_wait(&_TaskCount);
        pthread_mutex_lock(&_Mutex);

        Task = _Queue.front();
        _Queue.pop_front();

        pthread_mutex_unlock(&_Mutex);

        if (Task.Callee != NULL)
            Task.Callee->CallBackFunc(NULL, Task.CallParam);
    }
}
A: 

What could be wrong? Any number of things. Something else could be destroying the semaphore or overwriting the memory used to store it or the pointer to it. Another possibility is that you're calling sem_post() too many times and the counter overflows. A code sample would help.

Jim Mischel
I am experiencing the same problem and I don't know what could be happening. I've checked that the counter doesn't overflow and the memory is correct, but what is more strange is that sem_post returns -1 but the counter inside is correctly increased...
David Alfonso