Hi all, I''ve added some critical section methods to the Windows::Synchronize module in the windows-pr library (in CVS). Looking at the RUBY_CRITICAL macro from rubysig.h, it basically looks like this (in pure Ruby): def RUBY_CRITICAL(&block) critical_section = [0].pack(''L'') InitializeCriticalSection(critical_section) EnterCriticalSection(critical_section) block.call LeaveCriticalSection(critical_section) end But, shouldn''t we ensure that we leave the critical section once entered, like so? # This is what''s currently in CVS def RUBY_CRITICAL(&block) critical_section = [0].pack(''L'') begin InitializeCriticalSection(critical_section) EnterCriticalSection(critical_section) block.call ensure LeaveCriticalSection(critical_section) end end Or, am I worrying over nothing? Regards, Dan
Hi Dan, I certainly like the idea of ensuring that we leave the critical section once entered. However, there are some possible complications. For example, MSDN says: "Windows 2000/NT: In low memory situations, EnterCriticalSection can raise an exception. Do not attempt to handle this exception; instead, either terminate the process or allow the exception to pass to the unhandled exception filter. To avoid an exception due to low memory, call the InitializeCriticalSectionAndSpinCount function to preallocate the event used by EnterCriticalSection instead of calling the InitializeCriticalSection function, which forces EnterCriticalSection to allocate the event. Preallocating the event is not necessary on Windows XP or later because EnterCriticalSection is guaranteed not to fail due to lack of resources." http://msdn2.microsoft.com/en-us/library/ms682608.aspx Then again, I don''t think it''s too likely that we''d be low enough on memory for EnterCriticalSection to fail. Best regards, Wayne On 10/20/07, Daniel Berger <djberg96 at gmail.com> wrote:> Hi all, > > I''ve added some critical section methods to the Windows::Synchronize > module in the windows-pr library (in CVS). Looking at the RUBY_CRITICAL > macro from rubysig.h, it basically looks like this (in pure Ruby): > > def RUBY_CRITICAL(&block) > critical_section = [0].pack(''L'') > InitializeCriticalSection(critical_section) > EnterCriticalSection(critical_section) > block.call > LeaveCriticalSection(critical_section) > end > > But, shouldn''t we ensure that we leave the critical section once > entered, like so? > > # This is what''s currently in CVS > def RUBY_CRITICAL(&block) > critical_section = [0].pack(''L'') > begin > InitializeCriticalSection(critical_section) > EnterCriticalSection(critical_section) > block.call > ensure > LeaveCriticalSection(critical_section) > end > end > > Or, am I worrying over nothing? > > Regards, > > Dan > _______________________________________________ > win32utils-devel mailing list > win32utils-devel at rubyforge.org > http://rubyforge.org/mailman/listinfo/win32utils-devel >
Wayne Vucenic wrote:> Hi Dan, > > I certainly like the idea of ensuring that we leave the critical > section once entered. However, there are some possible complications. > For example, MSDN says: > > "Windows 2000/NT: In low memory situations, EnterCriticalSection can > raise an exception. Do not attempt to handle this exception; instead, > either terminate the process or allow the exception to pass to the > unhandled exception filter. To avoid an exception due to low memory, > call the InitializeCriticalSectionAndSpinCount function to preallocate > the event used by EnterCriticalSection instead of calling the > InitializeCriticalSection function, which forces EnterCriticalSection > to allocate the event. Preallocating the event is not necessary on > Windows XP or later because EnterCriticalSection is guaranteed not to > fail due to lack of resources." > http://msdn2.microsoft.com/en-us/library/ms682608.aspx > > Then again, I don''t think it''s too likely that we''d be low enough on > memory for EnterCriticalSection to fail.<snip> Hi Wayne, Yeah, I saw that. I guess I''m not especially worried about checking for low memory for two reasons. First, it seems we don''t have to worry about it with XP and later, which covers the majority of Windows users at this point I think. Second, I''m pretty sure the interpreter would die anyway if there were a memory allocation issue. But, now that I look at this code, I''m somewhat confused as to why they felt compelled to wrap methods like Dir.mkdir in a RUBY_CRITICAL block in the first place. Are they trying to make it thread safe? The Ruby interpreter isn''t thread safe to begin with. Are they trying to make create + chmod a single transaction? Seems overkill, and besides, the code in dir.c takes no such precaution for Unix. I''d really like to see the use cases for why this was used. Regards, Dan