Commit 29b48d3d2fba06182c708c2389c2a1a686a8cc65

Authored by Collin Hockey
1 parent 6b57d025

Fix condition variable usage in Command

Similar to the fixes for subscriber, without holding the waiter_lock_,
updating the waiting_done_ flag may cause deadlock. In the deadlock
example below, Thread1 is waiting for the response, thread 2 is
processing the response and updating the waiter_lock_ variable:

----------------------------------------------------
|        Thread 1          |       Thread 2        |
----------------------------------------------------
| locks 'waiter_lock_'     |                       |
| check 'waiting_done_'    |                       |
|                          | Update 'waiting done' |
|                          | Send notification     |
| begin waiting for signal |                       |
| *deadlocked*             |                       |
----------------------------------------------------
Showing 1 changed file with 4 additions and 1 deletions
src/command.cpp
@@ -64,7 +64,10 @@ template <class ReplyT> void Command<ReplyT>::processReply(redisReply *r) { @@ -64,7 +64,10 @@ template <class ReplyT> void Command<ReplyT>::processReply(redisReply *r) {
64 64
65 pending_--; 65 pending_--;
66 66
67 - waiting_done_ = true; 67 + {
  68 + unique_lock<mutex> lk(waiter_lock_);
  69 + waiting_done_ = true;
  70 + }
68 waiter_.notify_all(); 71 waiter_.notify_all();
69 72
70 // Always free the reply object for repeating commands 73 // Always free the reply object for repeating commands