Open p5pRT opened 9 years ago
based on work in https://github.com/ingydotnet/inline-c-pm/pull/31
on HP-UX (any posix perl is good enough for the example)
~$perl hang.pl
core delete-me2 hang.pl refreshperl
delete-me delete-me3 perl the_lock
~$core delete-me2 hang.pl refreshperl
delete-me delete-me3 perl the_lock
~$perl -v
This is perl, v5.8.3 built for PA-RISC1.1-thread-multi
(with 8 registered patches, see perl -V for more detail)
on Win32 with psuedofork 5.21.6
C:\sources\hang>perl hang.pl
Volume in drive C has no label.
Volume Serial Number is 4C2D-0BFA
Directory of C:\sources\hang
12/09/2014 11:49 PM <DIR> .
12/09/2014 11:49 PM <DIR> ..
12/09/2014 11:45 PM 404 hang.pl
12/09/2014 11:50 PM 0 the_lock
2 File(s) 404 bytes
2 Dir(s) 1,918,545,920 bytes free
*****hanged forever******
This is because CloseHandle or kernel mode equivelent during process exit resource cleanup is a blocking call that prevents the process object from exiting untill all its resources are freed. "dir" AKA cmd.exe inherited the handle in the flock from the parent OS process's child psudofork (note the "dir" was launched from the parent psuedoprocess). Adding "$^F = -1;" before the fork on Win32 Perl is of no help (the default is "2" on Win32 Perl (and all Perls I think). So $^F is either broken or NA (Im not sure what its supposed to exactly do in pp_sys.c), or needs to be implemented for Win32 perl. Also in code I dont see any uses of FD_CLOEXEC compiled in but I'm not sure if its because of "#if defined(HAS_FCNTL) && defined(F_SETFD)" or outer enclosing CPP macros. Is Win32 Perl supposed to support (in libc or emulated in win32/win32.c like alot of other posix things) FD_CLOEXEC and $^F? (assuming $^F does what I think its supposed to do).
This bug did/does affect a real world CPAN module so its marked medium priority.
related reading http://www.agent31.eu/2007/01/perl-windows-and-file-locking.html http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx but EXTENDED_STARTUPINFO_PRESENT isn't supported in XP/2003, so perl would have to serialize in perlhost.h/PERL_IMPLICIT_SYS, and remove then readd the inherit flag to libc file handles (good enough, rather than using debugging apis to get a list of all file handles in the process from NT kernel) with http://msdn.microsoft.com/en-us/library/windows/desktop/ms724935%28v=vs.85%29.aspx SetHandleInformation , if you think about it, isn't SetHandleInformation and HANDLE_FLAG_INHERIT the Win32 equivelent to FD_CLOEXEC?
So what is the plan for this bug? comments from p5p?
use Fcntl ':flock';
my $file = 'the_lock';
$^F = -1;
if(fork == 0){
sleep 1;
open my $lockfh, '>', $file or die "lockfile $file: $!";
flock($lockfh, LOCK_EX) or die "flock: $!\n";
flock($lockfh, LOCK_UN);
}
open my $lockfh, '>', $file or die "lockfile $file: $!";
flock($lockfh, LOCK_EX) or die "flock: $!\n";
sleep 2;
system($^O eq 'MSWin32' ? 'dir' : 'ls');
flock($lockfh, LOCK_UN);
This doesn't hang on Windows 7 x64.
Tony
The RT System itself - Status changed from 'new' to 'open'
Hangs on Server 2003 R2 SP2 x64 and XP SP3 x86 for me. Ill make a guess and say it hangs on \< NT 6.0 kernel. -- bulk88 ~ bulk88 at hotmail.com
Related reading http://blogs.msdn.com/b/oldnewthing/archive/2011/12/02/10243553.aspx
-- bulk88 ~ bulk88 at hotmail.com
I tested hang.pl on my Win7 32 bit. It didn't hang. That confirms its NT \<6 bug.
-- bulk88 ~ bulk88 at hotmail.com
Migrated from rt.perl.org#123402 (status was 'open')
Searchable as RT123402$