Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

64bit and 32bit process intercommunication boost::message_queue

Good day folks,

I am currently trying to figure a way to pass data between a 64bit process and a 32bit process. Since it's a real-time application and both are running on the same computer I tough using shared memory (shm).

While I was looking for some synchronization mechanism using shm, I felt on boost::message_queue. However it's not working.

My code is basically the following:

Sender part

message_queue::remove("message_queue");
message_queue mq(create_only, "message_queue", 100, sizeof(uint8_t));
for (uint8_t i = 0; i < 100; ++i)
{
    mq.send(&i, sizeof(uint8_t), 0);
}

Receiver part

message_queue mq(open_only, "message_queue");
for (uint8_t i = 0; i < 100; ++i)
{
    uint8_t v;
    size_t rsize;
    unsigned int rpriority;
    mq.receive(&v, sizeof(v), rsize, rpriority);
    std::cout << "v=" << (int) v << ", esize=" << sizeof(uint8_t) << ", rsize=" << rsize << ", rpriority=" << rpriority << std::endl;
}

This code works perfectly if the two process are 64bit or 32bit. But doesn't work if the two process aren't the same.

Looking deeper in boost (1.50.0) code you'll see the following line in message_queue_t::do_receive (boost/interprocess/ipc/message_queue.hpp):

scoped_lock lock(p_hdr->m_mutex);

For some reason, in the mutex seems to be locked when working with heterogeneous processes. My wild guess would be that the mutex is offsetted and therefore it's value is corrupted but I'm not quite sure.

Am I trying to accomplish something that is simply not supported?

Any help or advice will be appreciated.

like image 396
samuel Avatar asked Aug 11 '12 13:08

samuel


2 Answers

I think this is about the portability of offset_ptr used in message_queue to point to each message, including the header mutex. 32-/64-bit interoperability should be supported since Boost 1.48.0, as addressed in https://svn.boost.org/trac/boost/ticket/5230.

Following the ticket suggestion, the following definition has (so far) worked fine for me in leiu of message_queue:

typedef message_queue_t< offset_ptr<void, int32_t, uint64_t> > interop_message_queue;

On Boost 1.50.0 under MSVC this also seems to require a small patch in message_queue.hpp to resolve template ambiguity: casting arguments in calls to ipcdetail::get_rounded_size(...).

like image 169
James Beilby Avatar answered Sep 27 '22 18:09

James Beilby


I've spent my whole workday figure out the solution and finally I made it work. The solution is partially what James provided, so I used the interop_message_queue on both the 32-bit and the 64-bit processes.

typedef boost::interprocess::message_queue_t< offset_ptr<void, boost::int32_t, boost::uint64_t>> interop_message_queue;

The problem is that with this modification the code wouldn't compile, so I also had to add the following, which I found on the boost bug report list (#6147: message_queue sample fails to compile in 32-bit), this code has to be place before the boost includes of the message_queue:

namespace boost {
  namespace interprocess {
    namespace ipcdetail {
      //Rounds "orig_size" by excess to round_to bytes
      template<class SizeType, class ST2>
      inline SizeType get_rounded_size(SizeType orig_size, ST2 round_to) {
        return ((orig_size-1)/round_to+1)*round_to;
      }
    }
  }
}
like image 26
Tibor Gyimesi Avatar answered Sep 27 '22 18:09

Tibor Gyimesi