Hi Lincoln,

Thanks for the reply.

Lincoln A. Baxter wrote:
> Hey Steve,
> 
> I started to write you a message asking for a different strace, when I
> noticed that you are passing attributes for set_sig_handler that
> Sys::SigAction has no knowledge of:
> 
>   my $h = set_sig_handler('ALRM',sub {die "timeout";}, { trap => ['ALRM', 
> 'INT' ], safe=>0 });
> 
> The "trap" key in the hashref: { trap => ['ALRM', 'INT' ], safe=>0 } is
> not used by Sys::SigAction.
> 
> This reference is passed from set_sig_handler() (line 91) to
> mk_sig_action() (defined on line 94) where the 'flags' and the 'mask'
> keys are referenced (lines 98 and 99). 
> 
> Sys::SigAction does not know anything about the key 'trap'.  And i don't
> know how masking ALRM or INT can help you, and flags is used for setting
> sigaction flags usually in the form of SA_flag that are passed to
> sigaction() by perl.
> 
> Could you explain or fix this code, and then try again?

I've fixed the code, the 'trap' key was a typo - I've changed it to
'mask' as per the documentation:

 # Create database connection
 my($dbh);
 my($timeout) = 0;
 eval {
  no strict;
  my $h = set_sig_handler('ALRM', sub {$timeout=1; die "timeout";},
{mask=>['ALRM','INT'], safe=>0});
  alarm($alarm);
  $dbh = MailWatchCommon::db_connect();
  alarm(0);
 };
 alarm(0);
 if($@) {
  MailScanner::Log::WarnLog("MailWatch Error: Unable to initialise
database connection: %s", $@);
  DisableMailWatchLogging();
  return undef;
 }

Still no joy - the eval{} doesn't return on SIGALRM; here's the strace:

rt_sigprocmask(SIG_BLOCK, ~[RTMIN RT_1], [], 8) = 0
rt_sigaction(SIGALRM, NULL, {SIG_DFL}, 8) = 0
rt_sigprocmask(SIG_BLOCK, [ALRM], ~[KILL STOP RTMIN RT_1], 8) = 0
rt_sigaction(SIGALRM, {0xd30835, [], SA_RESTORER, 0xc29a98}, {SIG_DFL},
8) = 0
rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], NULL, 8) = 0
rt_sigaction(SIGALRM, {0xd3419d, [INT ALRM], SA_RESTORER, 0xc29a98},
NULL, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
alarm(30)                               = 0
rt_sigaction(SIGPIPE, {SIG_IGN}, {SIG_DFL}, 8) = 0
send(6, "Q\0\0\0\37SELECT \'DBD::Pg ping test\'\0", 32, 0) = 32
rt_sigaction(SIGPIPE, {SIG_DFL}, {SIG_IGN}, 8) = 0
poll([{fd=6, events=POLLIN|POLLERR}], 1, -1) = -1 EINTR (Interrupted
system call)
--- SIGALRM (Alarm clock) @ 0 (0) ---
rt_sigprocmask(SIG_UNBLOCK, [ALRM], NULL, 8) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 9
setsockopt(9, SOL_TCP, TCP_NODELAY, [1], 4) = 0
fcntl64(9, F_SETFL, O_RDONLY|O_NONBLOCK) = 0
fcntl64(9, F_SETFD, FD_CLOEXEC)         = 0
connect(9, {sa_family=AF_INET, sin_port=htons(5432),
sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in
progress)
poll(

This is on Linux 2.6.9, Perl 5.8.8, DBI 1.607 and DBD::Pg 2.10.7.

Is appears that the poll() interrupted by the alarm is simply restarted
again after by DBI or DBD::Pg.

Kind regards,
Steve.

Reply via email to