2014-07-09 10:10:33 POTENTIAL DEADLOCK DETECTED 2014-07-09 10:10:33 Previous lock order was: 2014-07-09 10:10:33 pnode->cs_vRecvMsg net.cpp:1541 2014-07-09 10:10:33 (1) cs_main main.cpp:3887 2014-07-09 10:10:33 (2) cs_vSend net.h:480 2014-07-09 10:10:33 Current lock order is: 2014-07-09 10:10:33 (2) pnode->cs_vSend net.cpp:1560 2014-07-09 10:10:33 (1) cs_main main.cpp:4387 2014-07-09 10:10:33 (1) cs_main main.cpp:1320
The problem seems to be:
- Many paths of execution will grab cs_main and then cs_vSend, eg. ProcessMessage("tx") locks cs_main and then can call pfrom->PushMessage if it rejects the tx. PushMessage() obtains pnode->cs_vSend. Another example: CheckBlock() will lock cs_main and then can call PushGetBlocks() which does a call to PushMessage() which locks pnode->cs_vSend.
- As far as I can tell, there is just a single execution path that obtains these locks in the opposite order: ThreadMessageHandler() locks pnode->cs_vSend and then calls SendMessages() which locks cs_main in order to call IsInitialBlockDownload().
The least painful fix seems to be to change the SendMessages() code to not need cs_main. Otherwise, ThreadMessageHandler() would need to lock cs_main prior to its SendMessages calls, which might be expensive use of the lock. Any ideas on making the IsInitialBlockDownload() check available to SendMessages() without it having to lock cs_main every time? Maybe caching it is possible?