Grygonos has asked for the wisdom of the Perl Monks concerning the following question:

Fellow Monks,

I have a daemon that runs and checks a database table, acting as a queue in this case, for a link to a config file of batch queries to be executed. If there is not an uncompleted batch of queries to run it sleeps. This process will run in definitely, "ideally". When it does shut down or I do have a need for it to shut down I was thinking I should trap the ^C and/or ^X and/or the dos box close and have the dbi disconnect the handle to the queue database all nice like.. I have zero expereince in signal trapping/handling at the os level, and sup search yielded very little help.

Any examples, links, pointers would be much appreciated. Thanks :)

Grygonos

Replies are listed 'Best First'.
Re: Signal Trapping..help please
by Ovid (Cardinal) on Dec 02, 2003 at 19:52 UTC

    Check out perldoc perlipc. To catch an interrupt signal:

    $SIG{INT} = sub { # handle the interrupt }

    You can test it with this:

    my $count = 0; $SIG{INT} = sub { print "\nCaught an interrupt\n"; exit if $count++ > 2 }; $|++; while (1) {print '.'; sleep 1}

    Edit: Of course, as zaxo pointed out below, since you are simply looking at gracefully disconnecting from the database, you probably don't need the signal handler.

    Cheers,
    Ovid

    New address of my CGI Course.

Re: Signal Trapping..help please
by Zaxo (Archbishop) on Dec 02, 2003 at 19:53 UTC

    You probably don't have to do anything. The default handler for SIGINT (Ctrl-C) does a graceful shutdown. Perl's ordinary destruction mechanism should close the DBI connection for you. If it doesn't, you can write a sub DESTROY which does that for you.

    After Compline,
    Zaxo

Re: Signal Trapping..help please
by holo (Monk) on Dec 02, 2003 at 20:05 UTC

    First off, you should try writing the program and ignore signals since Perl handles interrupt signals quite gracefully by default. If that does not work, you should add signal trapping as required.

    "How do I trap control characters/signals?" in perlfaq8 shows the most basic way of traping signals by using the %SIG hash. This is a very basic approach but might suffice for your purpose.

    On a Unix system, I would do this:

    $SIG{HUP} = \&reload; $SIG{TERM} = \&terminate; sub reload { # do whatever needs doing to restart } sub terminate { # terminate database connection, etc... }

    If you need to delay signals in some portions of your code though, you might want to take a look at the sig* routines in POSIX module.

    use POSIX qw(:signal_h); # do something # <criticalSection> my $sigSet = POSIX::SigSet->new; my $blockSet = POSIX::SigSet->new(SIGTERM, SIGHUP); die "Error restoring signal set: $!" unless sigprocmask(SIG_BLOCK, $blockSet, $sigSet) # do critical (uninterruptable) stuff die "Error restoring original signal set: $!" unless sigprocmask(SIG_SETMASK, $sigSet) # </criticalSection> # do other stuff here

    I don't see why this wouldn't work on Windows.