Duck Dodgers
Duck Dodgers

Reputation: 3461

scoped_lock() - an RAII implementation using pthread

I have a socket shared between 4 threads and I wanted to use the RAII principle for acquiring and releasing the mutex.


The ground realities

  1. I am using the pthread library.
  2. I cannot use Boost.
  3. I cannot use anything newer than C++03.
  4. I cannot use exceptions.

The Background

Instead of having to lock the mutex for the socket everytime before using it, and then unlocking the mutex right afterwards, I thought I could write a scoped_lock() which would lock the mutex, and once it goes out of scope, it would automatically unlock the mutex.

So, quite simply I do a lock in the constructor and an unlock in the destructor, as shown here.

ScopedLock::ScopedLock(pthread_mutex_t& mutex, int& errorCode)
: m_Mutex(mutex)
{
    errorCode = m_lock();
}

ScopedLock::~ScopedLock()
{
    errorCode = m_unlock();
}

where m_lock() and m_unlock() are quite simply two wrapper functions around the pthread_mutex_lock() and the pthread_mutex_unlock() functions respectively, with some additional tracelines/logging.

In this way, I would not have to write at least two unlock statements, one for the good case and one for the bad case (at least one, could be more bad-paths in some situations).


The Problem

The problem that I have bumped into and the thing that I don't like about this scheme is the destructor.

I have diligiently done for every function the error-handling, but from the destructor of this ScopedLock(), I cannot inform the caller about any errors that might be returned my m_unlock().

Upvotes: 2

Views: 774

Answers (1)

Petr Skocik
Petr Skocik

Reputation: 60117

This is a fundamental problem with RAII, but in this case, you're in luck. pthread_unlock only fails if you set up the mutex wrong (EINVAL) or if you're attempting to unlock an error checking mutex from a thread that doesn't own it (EPERM). These errors are indications of bugs in your code, not runtime errors that you should be taking into account. asserting errorCode==0 is a reasonable strategy in this case.

Upvotes: 2

Related Questions