Boost C++ Libraries: Ticket #7167: interprocess_condition doesn't implement move semantics https://svn.boost.org/trac10/ticket/7167 <p> Boost.Interprocess containers support move semantics, but interprocess_condition does not, which is problematic. </p> <p> For example, the lack of move semantics prevents having a boost::interprocess::map where the values are structs containing interprocess_condition variables. This is because map insert requires the value object to have move or copy constructors, both of which are impossible to implement correctly since the struct contains the non-copyable and non-moveable interprocess_condition member. (A work around is to store a pointer to the interprocess_condition in the Struct, but that shouldn't be necessary). </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/7167 Trac 1.4.3 John DiMatteo <jdimatteo@…> Tue, 24 Jul 2012 18:18:30 GMT <link>https://svn.boost.org/trac10/ticket/7167#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7167#comment:1</guid> <description> <p> This was discussed in the #boost irc.freenode.net channel a little bit: <br /> <br /> 12:32 &lt; JohnD&gt; I have a boost::interprocess::map&lt;pid_t, <a class="missing wiki">MyStruct</a>, std::less&lt;pid_t&gt;, <a class="missing wiki">MyAllocator</a>&gt; which was working fine until I added a boost::interprocess::interprocess_condition variable to <a class="missing wiki">MyStruct</a>, and now I can't compile because it needs a copy constructor -- why would I need a copy constructor if I'm not using the map [] syntax? <br /> 12:42 &lt; Zao&gt; A wild guess would be that that container, like most containers, copy on insertion. <br /> 12:44 &lt; mjcaisse&gt; I agree with Zao, though I'm having trouble finding that wording in the docs. interprocess containers are move aware though ... so you should be able to work around it. <br /> 12:44 &lt; mjcaisse&gt; JohnD: <sup> <br /> 2:45 &lt; JohnD&gt; mjcaisse / Zao: thanks, that I just found when I remove my insert I no longer need the copy constructor <br /> 12:45 &lt; JohnD&gt; so now I just need to see if I can get the move semantics working -- I was inserting a temporary so I thought move was implicit <br /> 12:46 &lt; mjcaisse&gt; JohnD: <a href="http://www.boost.org/doc/libs/1_50_0/doc/html/interprocess/allocators_containers.html#interprocess.allocators_containers.containers_explained.containers_and_move">http://www.boost.org/doc/libs/1_50_0/doc/html/interprocess/allocators_containers.html#interprocess.allocators_containers.containers_explained.containers_and_move</a> <br /> 12:47 &lt; mjcaisse&gt; JohnD: hmmm... that doesn't look helpful (o; I wonder if you can implement a "proper" constructor that will enable move for the container. <br /> 12:49 &lt; JohnD&gt; mjcaisse: that sounds promising, <a class="missing wiki">MyStruct</a> doesn't have any constructor specifically for move, I'll try that -- thanks! <br /> 13:10 &lt; JohnD&gt; mjcaisse: thanks, defining the move constructor fixed the problem, but I can't seem to get std::move nor boost::move to work with boost::interprocess::interprocess_condition <br /> 13:10 &lt; JohnD&gt; is boost::interprocess::interprocess_condition move aware? <br /> 13:11 &lt; mjcaisse&gt; JohnD: it *should* work with boost::move <br /> 13:11 &lt; JohnD&gt; (to be clear, the move constructor I defined compiles but is incorrect since I'm not properly moving the condition member variable) <br /> 13:12 &lt; JohnD&gt; mjcaisse: I'm using boost 1.49, and looking at interprocess_condition.hpp doesn't seem to show any move constructor being defined <br /> 13:17 &lt; mjcaisse&gt; JohnD: hmmm... I'm seeing the same thing )o: <br /> 13:22 &lt; JohnD&gt; the lack of a move constructor in interprocess_condition.hpp is a bug, right? is there a work around? <br /> 13:22 &lt; JohnD&gt; I think it is probably more likely that I'm doing something wrong, I'm skeptical I could actually find a bug in boost <br /> 13:24 &lt; mjcaisse&gt; JohnD: (o; <br /> 13:26 &lt; mjcaisse&gt; JohnD: so you are calling something like: my_map.insert( boost::move( pair&lt;key,value&gt;(k,v) ) ) <br /> 13:26 &lt; mjcaisse&gt; JohnD: which doesn't seem right either .... <br /> 13:28 &lt; JohnD&gt; mjcaisse: I'm doing the following: my_map.insert(std::pair&lt;const pid_t, <a class="missing wiki">MyStruct</a>&gt;(aPID, <a class="missing wiki">MyStruct</a>(mManagedSharedMemory, blah, blah))) <br /> 13:29 &lt; JohnD&gt; and that compiles fine as long as I defined the <a class="missing wiki">MyStruct</a>(<a class="missing wiki">MyStruct</a>&amp;&amp; a) <br /> 13:30 &lt; JohnD&gt; the problem lies when I try to move the interprocess_condition in that move constructor -- it isn't allowed <br /> 13:38 &lt; JohnD&gt; mjcaisse: I guess I don't *really* need to move the interprocess_condition member in the move constructor of <a class="missing wiki">MyStruct</a> -- if I am only doing the move constructor when inserting into the map there is nothing worth moving anyway -- does this sound right to you? obviously this is dangerous (e.g. in case someone else tries to use my move constructor outside of inserting a temporary), but I don't see what other options I have -- what do you think? <br /> 13:42 &lt; mjcaisse&gt; JohnD: that would be a way around the problem <br /> 13:42 &lt; mjcaisse&gt; JohnD: you could also do something sleazy like: <a class="missing wiki">MyStruct</a>&amp; v = my_map[key]; and then "initialize" v <br /> 13:45 &lt; mjcaisse&gt; JohnD: I see all of the example code is putting conditional variables and such into shared memory via new. I can't find anything via google on people trying to put them in containers <br /> 13:45 &lt; mjcaisse&gt; JohnD: but that seems like a perfectly normal use-case <br /> 13:53 &lt; JohnD&gt; mjcaisse: actually one of my coworkers just suggested I store the interprocess_condition as a pointer which would make the move semantics unnecessary (which I guess agrees with your googling), so I'll just do that for now <br /> 13:55 &lt; mjcaisse&gt; JohnD: the trick is you want to store it in shared memory (o; </sup></p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Wed, 15 Aug 2012 19:41:23 GMT</pubDate> <title>component changed; owner set https://svn.boost.org/trac10/ticket/7167#comment:2 https://svn.boost.org/trac10/ticket/7167#comment:2 <ul> <li><strong>owner</strong> set to <span class="trac-author">Ion Gaztañaga</span> </li> <li><strong>component</strong> <span class="trac-field-old">None</span> → <span class="trac-field-new">interprocess</span> </li> </ul> Ticket Ion Gaztañaga Fri, 24 Aug 2012 19:41:01 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/7167#comment:3 https://svn.boost.org/trac10/ticket/7167#comment:3 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">invalid</span> </li> </ul> <p> It's not possible to add move semantics to condition variables and mutexes, because the operating system but might store the address of the synchronization object internally. Because of this, pthread_xxx_t is not copyable and std::mutex and std::condition_variable are not copyable or movable. </p> <p> The only way to put objects with member conditions and mutexes in containers is to use node-based containers (list, map, set, stable_vector...) and use emplace(...) functions, which don't require move constructible elements. </p> Ticket John DiMatteo <jdimatteo@…> Fri, 24 Aug 2012 19:56:03 GMT <link>https://svn.boost.org/trac10/ticket/7167#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/7167#comment:4</guid> <description> <p> igaztanaga: sorry for the invalid bug report and thanks for the explanation! </p> </description> <category>Ticket</category> </item> </channel> </rss>