Le 21/12/12 11:14, Fredrik Orderud a écrit :
The implementation of boost::reverse_lock::~reverse_lock calls "lock" on the mutex retrieved from the provided lock. According to the documentation [1], "lock" can throw operation_not_permitted, resource_deadlock_would_occur or device_or_resource_busy exceptions. I don't see any catching of exceptions inside the destructor, and am therefore concerned about the exception safety of reverse_lock.

Could someone please explain if reverse_lock is designed to be exception safe?

If not, then I would guess that it could be made exception safe by moving the destructor implementation into an explicit "close" method, and assert on it being called in the destructor.


[1] http://www.boost.org/doc/libs/1_52_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_concepts.basic_lockable

Let me analyze each possible exception case for boost::mutex:

operation_not_permitted: if the thread does not have the privilege to perform the operation.

Couldn't we assume that if the thread was able to lock the mutex before it will have the rights?

resource_deadlock_would_occur: if the implementation detects that a deadlock would occur.
The current implementation is based on

[EDEADLK]
The current thread already owns the mutex.
As the reverse_lock has unlocked it, the thread can not own the mutex, so this error seems not plausible.

device_or_resource_busy: if the mutex is already locked and blocking is not possible.

I think this is an error on the documentation as lock is based on posix

"The pthread_mutex_lock() and pthread_mutex_trylock() functions will fail if:
[EINVAL]
The mutex was created with the protocol attribute having the value PTHREAD_PRIO_PROTECT and the calling thread's priority is higher than the mutex's current priority ceiling.

The pthread_mutex_trylock() function will fail if:

[EBUSY]
The mutex could not be acquired because it was already locked.

The pthread_mutex_lock(), pthread_mutex_trylock() and pthread_mutex_unlock() functions may fail if:

[EINVAL]
The value specified by mutex does not refer to an initialised mutex object.
[EAGAIN]
The mutex could not be acquired because the maximum number of recursive locks for mutex has been exceeded.

The pthread_mutex_lock() function may fail if:

[EDEADLK]
The current thread already owns the mutex.

The pthread_mutex_unlock() function may fail if:

[EPERM]
The current thread does not own the mutex.

These functions will not return an error code of [EINTR]."

Of course other model of Lockable could have other specificities. The question is, what can we do on the destructor if lock() throws? abort? ignore?

The current situation call terminate(). Ignoring the error seems not a good approach,  or is it?

Best,
Vicente