Fixes #9221 ("message_queue deadlock on linux")

[SVN r86316]
This commit is contained in:
Ion Gaztañaga
2013-10-15 08:02:09 +00:00
parent 5fb241ea57
commit a4ce866747
3 changed files with 217 additions and 61 deletions

View File

@@ -17,6 +17,7 @@
#include <boost/interprocess/allocators/node_allocator.hpp>
#include <boost/interprocess/detail/os_thread_functions.hpp>
#include <vector>
#include <iostream>
#include <cstddef>
#include <limits>
#include <memory>
@@ -222,12 +223,12 @@ bool test_serialize_db()
return true;
}
//]
static const int MsgSize = 10;
static const int NumMsg = 1000;
static char msgsend [10];
static char msgrecv [10];
static boost::interprocess::message_queue *pmessage_queue;
void receiver()
@@ -267,6 +268,83 @@ bool test_buffer_overflow()
return true;
}
//////////////////////////////////////////////////////////////////////////////
//
// test_multi_sender_receiver is based on Alexander (aalutov's)
// testcase for ticket #9221. Many thanks.
//
//////////////////////////////////////////////////////////////////////////////
static boost::interprocess::message_queue *global_queue = 0;
//We'll send MULTI_NUM_MSG_PER_SENDER messages per sender
static const int MULTI_NUM_MSG_PER_SENDER = 10000;
//Message queue message capacity
static const int MULTI_QUEUE_SIZE = (MULTI_NUM_MSG_PER_SENDER - 1)/MULTI_NUM_MSG_PER_SENDER + 1;
//We'll launch MULTI_THREAD_COUNT senders and MULTI_THREAD_COUNT receivers
static const int MULTI_THREAD_COUNT = 10;
static void multisend()
{
char buff;
for (int i = 0; i < MULTI_NUM_MSG_PER_SENDER; i++) {
global_queue->send(&buff, 1, 0);
}
global_queue->send(&buff, 0, 0);
//std::cout<<"writer thread complete"<<std::endl;
}
static void multireceive()
{
char buff;
size_t size;
int received_msgs = 0;
unsigned int priority;
do {
global_queue->receive(&buff, 1, size, priority);
++received_msgs;
} while (size > 0);
--received_msgs;
//std::cout << "reader thread complete, read msgs: " << received_msgs << std::endl;
}
bool test_multi_sender_receiver()
{
bool ret = true;
//std::cout << "Testing multi-sender / multi-receiver " << std::endl;
try {
boost::interprocess::message_queue::remove(test::get_process_id_name());
boost::interprocess::message_queue mq
(boost::interprocess::open_or_create, test::get_process_id_name(), MULTI_QUEUE_SIZE, 1);
global_queue = &mq;
std::vector<boost::interprocess::ipcdetail::OS_thread_t> threads(MULTI_THREAD_COUNT*2);
//Launch senders receiver thread
for (int i = 0; i < MULTI_THREAD_COUNT; i++) {
boost::interprocess::ipcdetail::thread_launch
(threads[i], &multisend);
}
for (int i = 0; i < MULTI_THREAD_COUNT; i++) {
boost::interprocess::ipcdetail::thread_launch
(threads[MULTI_THREAD_COUNT+i], &multireceive);
}
for (int i = 0; i < MULTI_THREAD_COUNT*2; i++) {
boost::interprocess::ipcdetail::thread_join(threads[i]);
//std::cout << "Joined thread " << i << std::endl;
}
}
catch (std::exception &e) {
std::cout << "error " << e.what() << std::endl;
ret = false;
}
boost::interprocess::message_queue::remove(test::get_process_id_name());
return ret;
}
int main ()
{
if(!test_priority_order()){
@@ -281,6 +359,10 @@ int main ()
return 1;
}
if(!test_multi_sender_receiver()){
return 1;
}
return 0;
}