Commit b7d6798cfce2f62620c16eab48921a72630f5fa4

Authored by Wiebe Cazemier
1 parent 73dbbddd

Prevent deadlocks on lock you already own

This was necessary for publishing will messages from the destructor of a
client, when you're connecting two clients with a will, no clean
session and the same ID.
Showing 1 changed file with 15 additions and 2 deletions
rwlockguard.cpp
@@ -36,10 +36,23 @@ void RWLockGuard::wrlock() @@ -36,10 +36,23 @@ void RWLockGuard::wrlock()
36 throw std::runtime_error("wrlock failed."); 36 throw std::runtime_error("wrlock failed.");
37 } 37 }
38 38
  39 +/**
  40 + * @brief RWLockGuard::rdlock locks for reading, and considers it OK of the current thread already owns the lock for writing.
  41 + *
  42 + * The man page says: "The current thread already owns the read-write lock for writing." I hope that is literally the case.
  43 + */
39 void RWLockGuard::rdlock() 44 void RWLockGuard::rdlock()
40 { 45 {
41 - if (pthread_rwlock_rdlock(rwlock) != 0)  
42 - throw std::runtime_error("rdlock failed."); 46 + int rc = pthread_rwlock_rdlock(rwlock);
  47 +
  48 + if (rc == EDEADLK)
  49 + {
  50 + rwlock = NULL;
  51 + return;
  52 + }
  53 +
  54 + if (rc != 0)
  55 + throw std::runtime_error(strerror(rc));
43 } 56 }
44 57
45 void RWLockGuard::unlock() 58 void RWLockGuard::unlock()