home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  

Perl CookbookPerl CookbookSearch this book

16.21. Timing Out an Operation

16.21.3. Discussion

The alarm function takes one argument: the integer number of seconds before the kernel sends your process a SIGALRM, that is, an alarm signal. It may be delivered after that time in busy time-sharing systems. The default action for SIGALRM is to terminate your program, so you should install your own signal handler.

Because this example should work no matter what operation is being timed out, we take some special precautions in case your long-running operation contains a slow syscall. Slow syscalls are those that don't return immediately, but await some external event, such as for I/O to happen or some sort of timer to go off. These external events include read (including readline, the <FH> operator), write, and open on certain devices, fifos, and sockets, as well as accept, connect, send, recv, flock, wait, waitpid, and of course, sleep. If the alarm hits while you're in a slow syscall and you simply catch the signal and return, you'll go right back into that syscall. That's because Perl automatically restarts syscalls where it's able to. The only way out of them is to raise an exception through die and then let eval catch it. (This works because the exception winds up calling the C library's longjmp(3) function, which is what really gets you out of the restarting syscall.)

The nested exception trap is because you cannot be sure that arbitrary code in your long-running operation isn't going to raise some exception of its own. If it did, then that would pop you out of the inner eval with the alarm still pending. You need to make sure to clear the alarm anyway. The second alarm 0 is in case the signal comes in after running the long-running operation, but before getting to the first alarm 0. If you don't do that, you would risk a tiny race condition—but size doesn't matter in race conditions; they either exist or they don't. And we prefer that they don't.

You cannot (usefully) give the alarm function a fractional number of seconds; if you try, it will be truncated to an integer. For precise timers, see Recipe 3.9.

Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.