Boost C++ Libraries: Ticket #4827: Windows vs POSIX interface distinction seems unnecessary https://svn.boost.org/trac10/ticket/4827 <p> More details can be found in the following thread <a class="ext-link" href="http://lists.boost.org/Archives/boost/2010/10/171733.php"><span class="icon">​</span>http://lists.boost.org/Archives/boost/2010/10/171733.php</a> </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/4827 Trac 1.4.3 Ion Gaztañaga Tue, 09 Nov 2010 16:57:49 GMT <link>https://svn.boost.org/trac10/ticket/4827#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4827#comment:1</guid> <description> <p> Sorry for the lack of contest but I would need more details on how to add kernel-lifetime shared memory with Native NT API. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Domagoj Šarić</dc:creator> <pubDate>Thu, 11 Nov 2010 22:18:45 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/4827#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4827#comment:2</guid> <description> <p> AFAICT it should be enough to call <a class="missing wiki">NtCreateSection</a> with OBJECT_ATTRIBUTES::Attributes </p> <blockquote> <p> (<a class="ext-link" href="http://msdn.microsoft.com/en-us/library/ff557749(VS.85).aspx"><span class="icon">​</span>http://msdn.microsoft.com/en-us/library/ff557749(VS.85).aspx</a>) set to OBJ_PERMANENT... </p> </blockquote> <p> Also look into: <a class="missing wiki">NtMapViewOfSection</a> <a class="missing wiki">NtMakeTemporaryObject</a> <a class="missing wiki">NtQuerySection</a> <a class="missing wiki">NtExtendSection</a> ... </p> <p> See <a class="ext-link" href="http://undocumented.ntinternals.net"><span class="icon">​</span>http://undocumented.ntinternals.net</a> ... </p> <p> Also, sometimes good/better information can be found in driver oriented documentation that use the Zw-prefixed functions (e.g. <a class="ext-link" href="http://www.osronline.com/ddkx/kmarch/k111_4oc2.htm"><span class="icon">​</span>http://www.osronline.com/ddkx/kmarch/k111_4oc2.htm</a>) which are equivalent to the Nt ones (but for kernel mode code)... </p> <p> ps. as mentioned in the original post, I'm willing to help...what I primarily want is a no-bloat/STL-uncluttered shared memory/mapped memory implementation (i.e. that 'looks' and 'acts' 'C++ kosher' but is optimizer-transparent enough so that it compiles to code nearly identical as if the OS calls were manually/hand coded, as was demonstrated in the post linked to in the trac ticket 4234)...so if you want I can try and provide such a collection of lower level layer primitives (that I've, as mentioned, already started developing for GIL.IO) which you can then wrap as needed... </p> <p> pps. this is a fork of the original thread: <a class="ext-link" href="http://lists.boost.org/Archives/boost/2010/10/172227.php"><span class="icon">​</span>http://lists.boost.org/Archives/boost/2010/10/172227.php</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Fri, 12 Nov 2010 16:29:48 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/4827#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4827#comment:3</guid> <description> <p> I think OBJ_PERMANENT requires privileges (<a class="missing wiki">SeCreatePermanent</a> or something similar) and if pagefile backed shared memory is created, then shared memory naming must conform global/local rules, and only privileged (<a class="missing wiki">SeCreateGlobalPrivilege</a>) processes (e.g. services) can create such global names to be shared across processes from different sessions/users. </p> <p> For IO in mapped files if you use Interprocess you only need to hold a mapped_region, which only a few pointers and size_t-s. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Domagoj Šarić</dc:creator> <pubDate>Sat, 20 Nov 2010 10:34:02 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/4827 https://svn.boost.org/trac10/ticket/4827 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">native_nt_permanent_section.cpp</span> </li> </ul> Ticket Domagoj Šarić Sat, 20 Nov 2010 10:47:29 GMT <link>https://svn.boost.org/trac10/ticket/4827#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4827#comment:4</guid> <description> <p> Hi, yes OBJ_PERMANENT does require both <a class="missing wiki">SeCreatePermanent</a> and <a class="missing wiki">SeCreateGlobalPrivilege</a>. <a class="missing wiki">SeCreateGlobalPrivilege</a> is IMO not a problem as: </p> <ul><li>administrators and services have it by default, which I consider a 'normal'/reasonable requirement (admin/service/daemon level access) in a 'secure' multi-user OS for any sort of global namespace 'pollution' </li><li>is required even by a Win32 solution (when not emulated with files ofcourse)... </li></ul><p> <a class="missing wiki">SeCreatePermanent</a> OTOH is by default held only by (services running under) <a class="missing wiki">LocalSystem</a>, however admins can gain it through impersonation. Considering that I can still imagine use cases/need for kernel-lifetime named shared objects only for special service/daemon types of processes and maybe special server-like applications (that one can reasonable expect to run with admin privileges) I'd say that IMO this still does not constitute a real problem. </p> <p> I've cobbled (and attached) a demonstration of the above and verified that it works on Win7 pro x64, Win7 home x64 and WinXP pro x86... ;) </p> <p> As argued in the first post on the boost.devel thread, regardless of the chosen underlying implementation, it is IMO wrong to make the majority of users/use cases (that do not require kernel lifetime shared objects capabilities) pay for the requirements of the minority by designing the interface (and then paying for it both in terms of 'fat' in the implementation and 'platform specific clutter' in the interface) in such a way as to always require/offer only kernel lifetime semantics... AFAICT an interface that would offer both scoped lifetime and kernel lifetime semantices would not suffer (or atleast suffer less) from the mentioned issues... </p> <p> Ad overhead: </p> <blockquote> <p> sizeof( mapped_region ) is 6 * sizeof( void * ) which is 5 (or 4 if you want to remember the size) sizeof( void * ) more than necessary (check in MSDN, it explicitly says that it is not necessary to hold on to the mapping handle but only the pointer returned by <a class="missing wiki">MapViewOfFile</a>()...)...However this is less of a concern when compared to other 'unnecessary' things one has to pay for to get to/construct a mapped_region...i.e. for constructing a file_mapping one has to pay for a std::string, interprocess-to-win32 flags translation, exceptions, granularity adjustment... This sort of 'fat' if not obvious from source can be readily seen by stepping through assembly in release mode...or, as demonstrated in the post linked to in the original trac ticket 4234, comparing the sizes of statically linked binaries, VC 10 /Oxs: </p> </blockquote> <p> int main( int /*argc*/, char * * /*argv*/ ) { return 0; } ~ 31 kB </p> <p> int main( int /*argc*/, char * * /*argv*/ ) { </p> <blockquote> <p> using namespace boost::interprocess; mapped_region region( file_mapping( "test", read_only ), read_only, 0, 0 ); return region.get_size(); </p> </blockquote> <p> } ~ 49 kB </p> <p> ~18 kB difference for what is otherwise a half a dozen OS API calls is IMO a bit too much (alhtough still a lot better than Boost.IOStreams)... </p> <p> ps. maybe we should move this discussion back to boost.devel (considering the size of the posts)... ;) </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Domagoj Šarić</dc:creator> <pubDate>Mon, 22 Nov 2010 17:35:32 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/4827#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4827#comment:5</guid> <description> <p> 'ps.' If you perhaps have not come across it already <a class="ext-link" href="http://technet.microsoft.com/en-us/sysinternals/bb896657.aspx"><span class="icon">​</span>http://technet.microsoft.com/en-us/sysinternals/bb896657.aspx</a> is a nice aid for testing memory mapping code on Windows ;) </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Fri, 01 Apr 2011 17:53:11 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/4827#comment:6 https://svn.boost.org/trac10/ticket/4827#comment:6 <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> Sorry, but this solution is not a general solution due to the need of priviledges. </p> Ticket Domagoj Šarić Sat, 02 Apr 2011 09:49:57 GMT status changed; resolution deleted https://svn.boost.org/trac10/ticket/4827#comment:7 https://svn.boost.org/trac10/ticket/4827#comment:7 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">invalid</span> </li> </ul> <p> I'm sorry but this is IMO a too quick/simple dismissal of the presented arguments. The issue identified by the ticked is the (possibly) unnecessary Windows vs POSIX interface distinction. In the linked-to boost.devel thread a proposal is given on how the _interface_ could be redesigned to erase this distinction and in the same thread and the comments for this ticked two proposals for the _implementation_ of this change are given, one of them being the Native NT API solution. </p> <p> Dismissing one implementation proposal does not invalidate the entire ticket. Further more, the dismissal of the one implementation proposal (the Native NT API one) is not validly argued. IOW why would the need of admin priviledges invalidate this solution? For this limitation to be enough to invalidate the proposal one would have to show that there is actual need/an actuall use case for kernel-life time memory mapped objects for non-admin users on the Windows platform. The very fact that the Windows platform explicitly does not allow this hints that probably this is not the way these things are done on that platform... </p> Ticket Ion Gaztañaga Sat, 02 Apr 2011 10:55:50 GMT <link>https://svn.boost.org/trac10/ticket/4827#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4827#comment:8</guid> <description> <p> Sorry, but IMO your reply is too quick. Several users have reported bugs regarding non-administrative user permission issues, so shared memory is definitely needed for non-administrative users. </p> <p> Maybe we should offer windows-centric new feature for permanent shared memory, but that's another story. Interprocess shared_memory_object is about portability. windows_shared_memory might be another issue. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Domagoj Šarić</dc:creator> <pubDate>Sat, 02 Apr 2011 17:28:25 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/4827#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4827#comment:9</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/4827#comment:8" title="Comment 8">igaztanaga</a>: </p> <blockquote class="citation"> <p> Sorry, but IMO your reply is too quick. Several users have reported bugs regarding non-administrative user permission issues, so shared memory is definitely needed for non-administrative users. </p> </blockquote> <p> Shared memory as such yes, but creation of global, kernel lifetime shared memory..is this also really required for non-admin users? </p> <blockquote class="citation"> <p> Maybe we should offer windows-centric new feature for permanent shared memory, but that's another story. Interprocess shared_memory_object is about portability. windows_shared_memory might be another issue. </p> </blockquote> <p> No, no...the point of the ticket was that there already exists an unnecessary Windows vs POSIX distinction in the interface...adding more windows-centric features would only make the problem worse...and, as you say, ...it is about portability... </p> <p> As explained in the boost.devel thread, this Win vs POSIX interface complication exists only because 'Boost.Interprocess' insists on the POSIX model that shared memory objects _must_ have kernel lifetime semantics on all platforms...If you give up on that premise, and provide two 'layers' or RAII wrappers for shared memory objects, one with scoped (or implicitly reference counted through the OS handle) life time semantics (like for normal C++ objects) and another with persistent/kernel life time this complication would (probably) vanish...Then you could implement the 'plain'/scoped shm on Windows using the native shared memory mechanisms (as there would no longer be any need for the file-system-persistency emulation) which would in turn remove the need for the separate windows_shared_memory... </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Sat, 02 Apr 2011 20:15:50 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/4827#comment:10 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4827#comment:10</guid> <description> <p> Interprocess insists on the POSIX model because it is the portable way that can be reliable and easily implemented in all OS and with all users. That's one of the main goals for all Boost libraries. In Interprocess review this was decided and it is not going to change. Windows reference-counted semantics are imposible to achieve reliably in POSIX (a process crash would leave the memory permanently) without kernel help and windows persistent shared memory needs special priviledges. So there is no discussion here. </p> <p> windows_shared_memory offers referece-counted semantics because they are useful for Windows users. Using OBJ_PERMANENT might be useful to implement shared memory for users accepting priviledge limitations, but not as a general solution. </p> <p> I'm sorry we don't share views on the library design but there is nothing we can do about it. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Domagoj Šarić</dc:creator> <pubDate>Mon, 04 Apr 2011 09:31:37 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/4827#comment:11 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4827#comment:11</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/4827#comment:10" title="Comment 10">igaztanaga</a>: </p> <blockquote class="citation"> <p> Interprocess insists on the POSIX model because it is the portable way that can be reliable and easily implemented in all OS and with all users. That's one of the main goals for all Boost libraries. </p> </blockquote> <p> I wouldn't be so eager to call this 'easy' considering the complications in implementation (the registry-temp-path dance, remove_shared_memory_on_destroy helper...) or even quite so portable considering the 'platform specific' 'pollution' of the interface... </p> <blockquote class="citation"> <p> In Interprocess review this was decided and it is not going to change. Windows reference-counted semantics are imposible to achieve reliably in POSIX (a process crash would leave the memory permanently) without kernel help and windows persistent shared memory needs special priviledges. So there is no discussion here. </p> </blockquote> <p> If "a possible process crash" was the only argument put forth in the review (I'm sorry I wasn't around then so I do not know) to justify this design then I beg to differ (on the "no discussion here"). AFAIK Boost is not designed around bugs, UB, abnormal termination or 'catastrophic failures' which, AFAICT, makes this argument bogus. Not to clean up memory mapped objects after a process is a POSIX design decision and Boost should not go out of its way to circumvent this first and foremost for the simple reason that it cannot. Even with the current Boost.Interprocess, if a POSIX-based process crashes (right) before the remove_shared_memory_on_destroy destructor is called the mapped object will also, AFAIK, 'leak'/'dangle'...Users using POSIX already are/have to be aware of this POSIX behaviour/semantics and be prepared to manually handle the cleanup (or decide not to)... </p> <p> ps. Windows persistent shared memory requires special privileges _for creation only_...is/was there a use case where a limited-user Windows application needs to create persistent shared memory? </p> <p> pps. no need to discuss reference counted semantics yet (I wasn't asking for those anyway), simple scoped mapped objects would be enough... </p> <blockquote class="citation"> <p> windows_shared_memory offers referece-counted semantics because they are useful for Windows users. Using OBJ_PERMANENT might be useful to implement shared memory for users accepting priviledge limitations, but not as a general solution. </p> </blockquote> <p> Well, at least having the option (to skip the emulation on Windows/use an alternate native implementation) would certainly be welcomed but it would still do nothing about the interface 'platform specificness'... </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Sat, 24 Dec 2011 18:30:59 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/4827#comment:12 https://svn.boost.org/trac10/ticket/4827#comment:12 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> </ul> Ticket