[interprocess] access dynamically accessed shared region in another process

Hi there, I'm trying to do IPC via boost.interprocess and use a dynamic buffer. This is on windows, debug mt, boost 1.38. To do this, I first create a shared segment and then a dynamic area in it. like this: struct transfer_buffer { void *buf; size_t bufsize; boost::interprocess::interprocess_mutex mutex; size_t dmember; } typedef boost::interprocess::managed_windows_shared_memory shared_segment; ... using namespace boost::interprocess; shared_memory_object::remove(bufname); struct transfer_buffer *ret = 0; shared_segment_ptr seg;// I use a ptr to store the object away so it won't get lost seg.reset(new shared_segment(create_only, bufname, begin_size)); // and our maintanance struct in it ret = seg->construct<struct transfer_buffer>(unique_instance)(); ret->dmember = 42; const std::size_t Alignment = 128; ret->bufsize = 1982781; ret->buf = seg->allocate_aligned(ret->bufsize, Alignment); Then, process A writes into the dynamic buffer, which seems to work OK. In the other process however, I try to open it and read the data. Like this: seg.reset(new shared_segment(open_only, bufname)); ret = seg->find<struct transfer_buffer>(unique_instance).first; Now I can access everything fine in ret (the struct itself), including the mutex and data members. But I cannot access the dynamically allocated buffer. As soon as I access it (read it, memcpy, anything) the app crashes with what would appear to be a rather broken callstack. When I look at the transfer_buffer struct before the crash it looks as if the dynamic pointer points to some inaccessable area. Not what I wrote in it anyway. Do I have to do anything else (other than creating the segment and find() the unique transfer_buffer struct) in the other process to access the dynamic area? Or is this a bug? Any help appreciated... Stephan

To do this, I first create a shared segment and then a dynamic area in it. like this:
struct transfer_buffer { void *buf; size_t bufsize; boost::interprocess::interprocess_mutex mutex; size_t dmember; }
I only quickly looked at your code, but I think that your void* pointer is invalid in the second process. Take a look at boost::interprocess::offset_ptr and use it in place of void*. ~Dan

Casimiro, Daniel C CIV NUWC NWPT wrote:
To do this, I first create a shared segment and then a dynamic area in it. like this:
struct transfer_buffer { void *buf; size_t bufsize; boost::interprocess::interprocess_mutex mutex; size_t dmember; }
I only quickly looked at your code, but I think that your void* pointer is invalid in the second process.
Take a look at boost::interprocess::offset_ptr and use it in place of void*.
~Dan
Thanks for the quick reply, Dan. Yes, all pointers placed in shared memory should be offset_ptr as explained here: http://www.boost.org/doc/libs/1_38_0/doc/html/interprocess/sharedmemorybetwe... Regards, Ion

Am Mittwoch, 1. April 2009 18:58:39 schrieb Ion Gaztañaga:
Thanks for the quick reply, Dan. Yes, all pointers placed in shared memory should be offset_ptr as explained here:
http://www.boost.org/doc/libs/1_38_0/doc/html/interprocess/sharedmemorybetw eenprocesses.html#interprocess.sharedmemorybetweenprocesses.mapped_region_ob ject_limitations
Thanks for the quick reply!
Meanwhile I suspected as much, but didn't know for sure how to interpret the
docs.
Also, this alignment check taken from the docs doesn't compile anymore with a
pointer type as such:
struct transfer_buffer {
boost::interprocess::offset_ptr<void> buf;
size_t bufsize;
};
...
ret->bufsize = SIZE;
ret->buf = seg->allocate_aligned(ret->bufsize, Alignment);
// Check alignment
assert((static_cast

Meanwhile I suspected as much, but didn't know for sure how to interpret the docs. Also, this alignment check taken from the docs doesn't compile anymore with a pointer type as such:
struct transfer_buffer { boost::interprocess::offset_ptr<void> buf; size_t bufsize; }; ... ret->bufsize = SIZE; ret->buf = seg->allocate_aligned(ret->bufsize, Alignment);
// Check alignment assert((static_cast
(ret->buf) - static_cast (0)) % Alignment == 0);
Obviously, offset_ptr is not a pointer so it can be static_cast'ed.
offset_ptr is a smart pointer that emulates a pointer that can be placed
in shared memory. See offset_ptr docs and implementation for more
details. Try
// Check alignment
assert((static_cast
0);
Regards, Ion

Am Mittwoch, 1. April 2009 21:13:33 schrieb Ion Gaztañaga:
// Check alignment assert((static_cast
(ret->buf) - static_cast (0)) % Alignment == 0); Obviously, offset_ptr is not a pointer so it can be static_cast'ed. offset_ptr is a smart pointer that emulates a pointer that can be placed in shared memory. See offset_ptr docs and implementation for more details. Try
// Check alignment assert((static_cast
(ret->buf.get()) - static_cast (0)) % Alignment == 0);
Indeed. That was what I tried first. But that doesn't work either:
The compiler says "invalid use of »void«"
However, this does:
assert((static_cast
participants (3)
-
Casimiro, Daniel C CIV NUWC NWPT
-
Ion Gaztañaga
-
Stephan Menzel