<?xml version="1.0" encoding="windows-1252"?>
<node id="628706" title="On timing out with ALRM" created="2007-07-25 11:39:11" updated="2007-07-25 07:39:11">
<type id="115">
perlquestion</type>
<author id="439528">
tlm</author>
<data>
<field name="doctext">
&lt;p&gt;
The standard technique for timing-out long-running procedures in Perl is something like this:
&lt;/p&gt;
&lt;c&gt;
{
  local $SIG{ ALRM } = sub { die 'timeout' };
  alarm( MAX_SECONDS );
  eval {
    molasses_in_january();
    alarm( 0 );
  };
  if ( $@ ) {
    die if $@ !~ /timeout/;
    handle_timeout();
  }
}
&lt;/c&gt;

&lt;p&gt;(The Perl Cookbook, q.v., gives a slightly more elaborate technique featuring a second &lt;c&gt;eval&lt;/c&gt; inside the first one, but the basic idea is the same.)
&lt;/p&gt;

&lt;p&gt;One serious problem with this technique is that it requires that the code running in the &lt;i&gt;dynamic&lt;/i&gt; scope inside the eval does not itself use an eval, or, if it does, that it faithfully propagates our timeout error.  These are very shaky assumptions...&lt;/p&gt;

&lt;p&gt;In fact, I find myself now using a library written (badly) by someone else, and I'm finding that I can't safely timeout a certain long-running procedure because somewhere deep into the called code there's an eval that looks something like this&lt;/p&gt;

&lt;c&gt;
$cowbell = eval { more_cowbell() };
# eval errors blithely ignored

...

# in some other code, far, far away
die 'i got a fever' unless $cowbell;
&lt;/c&gt;

&lt;p&gt;This means that the code after my eval cannot distinguish between a timeout and some other error that may have happened...&lt;/p&gt;

&lt;p&gt;And to make matters worse, due to the widespread uses of careless &lt;c&gt;eval&lt;/c&gt;'s like this one, I don't even know exactly which one of all of them is ultimately responsible for trapping and ignoring my ALRM signal.  (My rendition of the problematic code radically simplifies the problem; in reality the relationship between the variables initialized as results of rogue &lt;c&gt;eval&lt;/c&gt;'s and the test that ultimately triggers the &lt;c&gt;die&lt;/c&gt; statement is far more baroque and unclear than what I'm showing.)&lt;/p&gt;

&lt;p&gt;I suppose that I could time the operation and use the measured elapsed time as a heuristic to decide whether the uninformative error message corresponds to a "real" error or to a disguised time-out error.  But this is a very crude workaround.&lt;/p&gt;

&lt;p&gt;Is there something better?&lt;/p&gt;

&lt;p&gt;Also, any trick that may help spot which of all the evals in the alien code is responsible for this particular mess would be appreciated.&lt;/p&gt;

&lt;p&gt;TIA!&lt;/p&gt;

&lt;div class="pmsig"&gt;&lt;div class="pmsig-439528"&gt;
&lt;p&gt;&lt;small&gt;the lowliest monk&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;</field>
</data>
</node>
