Subject: | Incompatibility with fork() |
If the service uses 'fork()' to start a child process (implemented as a
thread on Win32), when the child process ends the service change state
to SERVICE_STOP_PENDING and shutdown.
The consequence is that we can not implement a cron-like service.
I'm attaching a test case:
- PerlService.inf is the script to install the service (right click,
"Install" from the Windows Explorer) and uninstall (use the Control
Panel to uninstall "Perl service demo").
- test-PCDW.pl: the daemon
Here is the output:
Fri Sep 25 17:05:55 2009 Begin
Fri Sep 25 17:05:56 2009 2
Fri Sep 25 17:05:57 2009 4
Fri Sep 25 17:05:58 2009 4
Fri Sep 25 17:05:59 2009 4
Fri Sep 25 17:06:00 2009 4
Child start
Fri Sep 25 17:06:01 2009 4
Fri Sep 25 17:06:02 2009 4
Fri Sep 25 17:06:03 2009 4
Fri Sep 25 17:06:04 2009 4
Fri Sep 25 17:06:05 2009 4
Child end
Fri Sep 25 17:06:06 2009 3
Fri Sep 25 17:06:07 2009 1
Fri Sep 25 17:06:07 2009 End
--
Olivier Mengué - http://o.mengue.free.fr/
Subject: | test-PCDW.pl |
#!/usr/bin/perl
use utf8; # vim:set sts=4 sw=4 et:
use strict;
use warnings;
use POE qw(Component::Daemon::Win32);
my $log_file = @ARGV ? $ARGV[0] : "$0.log";
open(my $log, '>:utf8', $log_file);
select( (select($log), $| = 1 )[0] ); # Autoflush
close(STDOUT);
close(STDERR);
*STDOUT = *STDERR = $log;
my $count = 0;
sub service_state
{
my ($state, $message) = @_[ARG0, ARG1];
print scalar localtime(), ' ', $state, "\n";
# service start pending
if ($state == SERVICE_START_PENDING) {
# do some sort of initialization here
}
if ($state == SERVICE_RUNNING) {
$count++;
if ($count == 4) {
my $pid = fork();
unless ($pid) {
print "Child start\n";
sleep 5;
print "Child end\n";
exit 0;
}
}
}
$poe_kernel->yield ('next_state');
}
print scalar localtime(), " Begin\n";
POE::Component::Daemon::Win32->spawn(
Alias => 'svc',
Callback => \&service_state,
PollInterval => 1,
);
POE::Kernel->run;
print scalar localtime(), " End\n";
Subject: | PerlService.inf |
Message body not shown because it is not plain text.