I'm getting a race condition in some Linux::Inotify2 code. Where I'm watching a directory for IN_CREATE events to process the created files. The following works perfectly 99% of the time.
use strict; use warnings; use XML::LibXML; use Linux::Inotify2; my $drop_dir = "/foo/bar"; my $inotify = Linux::Inotify2->new or die "unable to create new inotify object: $!"; $inotify->watch($drop_dir, IN_CREATE, sub { my $e = shift; my $name = $e->fullname; process_drop_file($name); }); 1 while $inotify->poll; sub process_drop_file { my $file = Path::Class::File->new(shift); -f $file or croak "'$file' is not a file"; my $doc = XML::LibXML->new->parse_file("$file"); # Do stuff with it... $file->remove or croak "Couldn't remove '$file'"; }
But then bam-
/foo/bar/test.xml:1: parser error : Start tag expected, '<' not found
The file is there and in tact by the time I can manually check of course but XML::LibXML tried to read it too early. This means it passed the -f but had no content, I think.
Among several other dead-ends, like playing with the cookie and watch args, I tried this-
$inotify->watch($drop_dir, IN_CREATE, sub { my $e = shift; my $name = $e->fullname; $inotify->watch($name, IN_CLOSE, sub { process_drop_file($name); }); });
-in a misguided attempt to move the event check to the file, but of course this could only succeed in the 1 in 100 case where the race condition hits.
What am I missing or doing wrong? Thank you!
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |