<html lang="en">
<head>
<title>Schiffmans timeout</title>

<META content="text/html; charset=windows-1252" http-equiv=Content-Type>
<STYLE type=text/css>
p {clear:left}
hr {clear:left}

pre.codeExample {width: auto;
    float: left;
    color: rgb (0, 0, 0);
    background: rgb(190,250,190);
    border: solid rgb(190,250,190); 
    border-width: 12; 
    margin-left: 1em;
    margin-right: 1em;
}
hr.endOfHeader {
   width: 80%
}

hr.startOfFooter {
   width: 80%
}
</STYLE>

</head>

<body>

<h2>Fun with Exception-Handling Part I<br>
by Allan M. Schiffman</h2>
<p>Source:<br>
ParcPlace Newsletter<br>
Autumn 1989, number 4
page 10.</p>
<small  style="color:#FF0000">Note that this code is not immediately useable in Squeak</small>
<hr class="endOfHeader">

<p>Using the new Smalltalk-80 exception-handling facility
(introduced in version 2.4 and enhanced in version 2.5) is a
heady experience. If you're like me, after you use exception-handling
for awhile, all sorts of weird control structures you could 
create pop into mind, leaving you faintly unnerved with how easy it was.
And I have this unsettling image of myself hanging somewhere, with
plenty of rope left over ...</p>
<p>Here's one that occured to me recently - how about being
able to terminate a computation if if "takes too long",
returning an easier to compute answer instead? For example, you were
mildly interested in how much object memory you were using,
but weren't willing to wait very long to find out, you
could evaluate:</p>

<pre class="codeExample">[Smalltalk core]                               <i>"sometimes takes &gt; 10 seconds"</i>
  valueOnTimeoutMs: 5000                       <i>"willing towait 5 seconds"</i>
  do: [Transcript cr;show: 'only guessing'.
       #(35000 1800000)                        <i>"answer a wild guess if timeed-out"</i>
      ]</pre>

<p>The code for class <b>BlockClosure</b>'s message <b>valueOnTimeoutMs:do:</b>
provided here creates a watchdog process which waits on an appropriate
delay. The watchdog uses class <b>Process</b>'s message <b>interruptWith:</b>
to raise an exception in the original process, which has a handler that
runs the timeout block when invoked.</p>
<p>Well, now that it's off my chest, I feel guilty, but better. More next issue!</p>


<pre class="codeExample"><b>valueOnTimeoutMs: milliseconds do: timeoutBlock</b>
     <i>"Evaluate the block (the receiver) and answer the result, if that
      evaluation completes in the given number of milliseconds. If not,
      evaluate the timeoutBlock and answer its result instead."</i>
   | theProcess watchdog done dsem delay sig |
  <i>"make a special timeout signal"</i>
sig := Object informationSignal newSignal.
  <i>"the block will be executed in the current process"</i>
theProcess := Processor activeProcess.
delay := Delay forMilliseconds: milliseconds.
  <i>"get the delay's semaphore so it can be signalled elsewhere too"</i>
dsem := delay delaySemaphore.
  <i>"make a watchdog process"</i>
watchdog :=
   [delay wait.               <i>"wait for timeout or completion"</i>
    done ifFalse: [theProcess interruptWith: [sig raise]]] newProcess.
  <i>"watchdog needs to run at high priority to do its job"</i>
watchdog priority: Processor timingPriority.
^sig                          <i>"catch the timeout signal"</i>
  handle: [:ex | ex returnWith: timeoutBlock value]
  do: [ | result |
       done := false.
       watchdog resume.       <i>"start up the atchdog"</i>
       result := self value.  <i>"now evaluate the block..."</i>
       done := true.          <i>"its completed, so ..."</i>
       dsem signal.           <i>"arrange for the watchdog to exit"</i>
       result]</pre>

<hr class="startOfFooter">
<p>Allan is a senior member of the technical staff at ParcPlace</p>
</body>
</html>