Boost C++ Libraries: Ticket #2796: interprocess::file_lock has incorrect behavior when win32 api is enabled https://svn.boost.org/trac10/ticket/2796 <p> (Above all else, I must say.... boost is awesome. I am raving fan of boost. Many, many thanks to all the talented boost developers.) </p> <p> BUG DESCRIPTION: </p> <p> Either the IPC file_lock documentation needs fixing, or else there is a bug in the way file_lock uses win32 file handles and <a class="missing wiki">LockFileEx</a>. </p> <p> This part of the boost documentation is incorrect when the win32 api is enabled: </p> <p> <a href="http://www.boost.org/doc/libs/1_36_0/doc/html/interprocess/synchronization_mechanisms.html#interprocess.synchronization_mechanisms.file_lock.file_lock_careful_iostream">http://www.boost.org/doc/libs/1_36_0/doc/html/interprocess/synchronization_mechanisms.html#interprocess.synchronization_mechanisms.file_lock.file_lock_careful_iostream</a> </p> <p> The problem with the sample code at the above URL is that on windows, "fstream file" and "file_lock f_lock" both will hold TWO DIFFERENT file handles. Of course both of those objects wrap the same exact file on disk, but it is _crucial_ (and in this case deadly) to realize that they wrap different HANDLES. </p> <p> So... when using the win32 api in boost file_lock, the last line of code in the sample from the URL will always fail. </p> <p> This will always fail: </p> <blockquote> <p> file.flush(); </p> </blockquote> <p> Windows will produce an ERROR_LOCK_VIOLATION. As I explain below, the reason why this happens is that locking in the windows api actually locks write-access to the file based on the HANDLE, not based on the process (pid) that obtained the locking rights. </p> <p> This basically makes boost file_lock incompatible, or not successfully ported, to windows. I essentially "lock myself out of the file" when I use the file_lock. Obviously that is _not_ what one wants. We want to lock other processes out of the file, but not lock ourselves out. </p> <p> Please note the following win32 documentation: </p> <p> <a class="ext-link" href="http://msdn.microsoft.com/en-us/library/aa365203(VS.85).aspx"><span class="icon">​</span>http://msdn.microsoft.com/en-us/library/aa365203(VS.85).aspx</a> </p> <p> The interesting part about <a class="missing wiki">LockFileEx</a> is the following: </p> <p> "Remarks ..... </p> <blockquote> <p> If the locking process opens the file a second time, it cannot access the specified region through this second handle until it unlocks the region..... " </p> </blockquote> <p> The important thing about that is that <a class="missing wiki">LockFileEx</a> is doing <strong>MORE</strong> than making sure foreign processes are locked out of my file. <a class="missing wiki">LockFileEx</a> will also keep <strong>my</strong> process (the process obtaining the lock) from writing to the file, unless I am careful to use an IDENTICAL file handle. </p> <p> As far as I can see, this makes <a class="missing wiki">LockFileEx</a> very different from flock(). </p> <p> So, if I am to follow the windows advice for using <a class="missing wiki">LockFileEx</a>, then I believe what I need to do is make sure that the same file handle I use to write to my file is IDENTICAL to the file handle used by my boost file_lock object. </p> <p> Unfortunately, I cannot see any way to do this. And unless I can find a way, then it seems like boost::interprocess:file_lock is not useful at all when the win32 api is enabled. </p> <p> in the ctor of the file_lock, "open_existing_file" is called, which calls the winapi function CreateFileA. </p> <p> CreateFileA gives you a new file handle. This file handle is stored (privately) in: </p> <blockquote> <p> file_lock::m_file_hnd </p> </blockquote> <p> When you then proceed to _lock_ the file_lock, the winapi function <a class="missing wiki">LockFileEx</a>. </p> <p> <a class="missing wiki">LockFileEx</a> takes a handle as an argument. As we would expect, the handle that gets passed in is the same handle as file_lock::m_file_hnd. </p> <p> The problem is that the win32 api will now lock out (prevent) all writes to the file that are not writing via that same file handle. </p> <p> That means that even the process that obtained and now holds the locked file_lock is prevented from writing to the file. </p> <p> This is the windows error that happens: </p> <p> 33 The process cannot access the file because another process has locked a portion of the file. ERROR_LOCK_VIOLATION </p> <p> Because "file_lock::m_file_hnd" is a private member, I cannot see any way for me to use any object (and file object, whether it be a win32 object that I construct, or a std::fstream, or some other file object)... I cannot see a way for myself to get a file object with the SAME handle as file_lock::m_file_hnd, which is what I must do if I even am going to actually write to the file that i have locked with file_lock. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/2796 Trac 1.4.3 Kelly K. Heller <kkheller@…> Wed, 25 Feb 2009 17:23:05 GMT version changed https://svn.boost.org/trac10/ticket/2796#comment:1 https://svn.boost.org/trac10/ticket/2796#comment:1 <ul> <li><strong>version</strong> <span class="trac-field-old">Boost 1.37.0</span> → <span class="trac-field-new">Boost 1.38.0</span> </li> </ul> Ticket Ion Gaztañaga Fri, 01 Apr 2011 21:35:32 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/2796#comment:2 https://svn.boost.org/trac10/ticket/2796#comment:2 <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">fixed</span> </li> </ul> <p> Changed documentation in Boost 1.47 </p> Ticket Kelly Heller <kkheller@…> Fri, 15 Jul 2011 18:37:21 GMT <link>https://svn.boost.org/trac10/ticket/2796#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2796#comment:3</guid> <description> <p> I would be very interested to know the text that has been changed or added in the new documentation. I compared the 1.36 documentation to the current 1.47 documentation today, and I cannot find any updates related to this bug case. Thank you for your help. </p> </description> <category>Ticket</category> </item> <item> <author>Dominik Wild <d.wild@…></author> <pubDate>Wed, 17 Aug 2011 14:31:02 GMT</pubDate> <title>status changed; resolution, milestone deleted https://svn.boost.org/trac10/ticket/2796#comment:4 https://svn.boost.org/trac10/ticket/2796#comment:4 <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">fixed</span> </li> <li><strong>milestone</strong> <span class="trac-field-deleted">Boost 1.39.0</span> </li> </ul> <p> The bug description is accurate. Neither the code nor the documentation were fixed in 1.47. </p> <p> Others have experienced this bug as well: <a class="ext-link" href="http://stackoverflow.com/questions/5425064/scoped-lock-doesnt-work-on-file"><span class="icon">​</span>http://stackoverflow.com/questions/5425064/scoped-lock-doesnt-work-on-file</a> </p> Ticket Ion Gaztañaga Sat, 24 Dec 2011 18:42:56 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/2796#comment:5 https://svn.boost.org/trac10/ticket/2796#comment:5 <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">fixed</span> </li> </ul> <p> It was actually fixed in Boost.1.48, as the change was not merged to release branch for Boost 1.47. In the example, the name of the lock file was changed and a note warning about windows behaviour is added. If we want to use native file locking functions from winows we can't much more. </p> Ticket sumeet@… Fri, 11 May 2012 00:55:13 GMT <link>https://svn.boost.org/trac10/ticket/2796#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2796#comment:6</guid> <description> <p> I found the same issue the hard way. I must say the documentation is still misleading, otherwise I wouldn't have gone down this path. I'm going to try named mutexes now... </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Fri, 11 May 2012 00:57:03 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/2796#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/2796#comment:7</guid> <description> <p> Boost rocks though. Thanks for all your efforts. Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/2796#comment:6" title="Comment 6">sumeet@…</a>: </p> <blockquote class="citation"> <p> I found the same issue the hard way. I must say the documentation is still misleading, otherwise I wouldn't have gone down this path. I'm going to try named mutexes now... </p> </blockquote> </description> <category>Ticket</category> </item> </channel> </rss>