Commit b7d6798cfce2f62620c16eab48921a72630f5fa4
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() |