ckazer
ckazer

Reputation: 13

Why am I receiving a lock assertion failure for a simple boost producer/consumer program?

I'm working on creating a simple threaded producer/consumer example using separate classes, c++ standard library deques, and boost threads on Linux. I'm passing a shared buffer, lock, and condition variables by reference as member variables to my classes. The threads start up ok, but typically crash at a random time due to a lock assertion error.

main: ../nptl/pthread_mutex_lock.c:80: __pthread_mutex_lock: Assertion `mutex->__data.__owner == 0' failed.

Here's how I'm starting the threads in main

std::deque<double> buf;
boost::condition_variable_any buf_has_space;
boost::condition_variable_any buf_has_data;
boost::mutex buf_lock;

boost::thread producerThread(load_func, &buf, &buf_has_space, &buf_has_data, &buf_lock);
boost::thread consumerThread(consume_func, &buf, &buf_has_space, &buf_has_data, &buf_lock);

producerThread.join();
consumerThread.join();

producerThread and consumerThread initialize and run instances of myProducer and myConsumer.

Relevant code from myProducer:

void myProducer::add_to_buffer(){
    //Main loop
    for (int i=0; i<100000; i++){
        boost::mutex::scoped_lock lock(*buffer_lock);
        while (buffer->size() == max_size){
            buffer_has_space->wait(*buffer_lock);
        }
        buffer->push_back(i);
        buffer_has_data->notify_one();
        buffer_lock -> unlock();
    }

    //Consumer will stop when it sees -1
    boost::mutex::scoped_lock lock(*buffer_lock);
    while (buffer->size() == max_size){
        buffer_has_space->wait(*buffer_lock);
    }
    buffer->push_back(-1.0);
    buffer_has_data->notify_one();
    buffer_lock -> unlock();
}

Relevant code from myConsumer:

void myConsumer::load_from_buffer(){
    double current = 0;
    while (current != -1.0) {
        boost::mutex::scoped_lock lock(*buffer_lock);
        while (buffer->size() == 0){
            buffer_has_data->wait(*buffer_lock);
        }
        current = buffer->front();
        buffer->pop_front();
        buffer_has_space->notify_one();
        buffer_lock->unlock();
        std::cout << current <<"\n";
    }
}

I've looked at these questions:

pthread_mutex_lock.c:62: __pthread_mutex_lock: Assertion `mutex->__data.__owner == 0' failed

Pthread mutex assertion error

However, the program is crashing before my classes are deconstructed, and each lock is matched with an unlock in the same thread.

Upvotes: 1

Views: 1991

Answers (1)

sehe
sehe

Reputation: 392833

If you have the lock owned by a lock guard (scoped_lock) it's an error to manually manipulate the lock.

If you must manipulate the lock before the end of the scope, you can do so on the scoped_lock itself:

lock.unlock();  // instead of buffer_lock -> unlock();

Upvotes: 2

Related Questions