[concurrency-interest]yet another proposal for Executor

Mark D. Anderson mda@discerning.com
Wed, 6 Feb 2002 16:20:44 -0800


> I'm a little unclear on exactly how cancel() is intended to be used. From
> what I recall it is meant to be a "cleanup function" of some sorts, but is
> to be called *before* actually unqueing/interrupting - right? But if it is
> called before unqueuing then cancel() and run() have to coordinate to ensure
> that if the task is executed before it is unqueued then it won't do anything
> that conflicts with the cancel (presumably check a cancel flag and return).
> But if that is the case then why not unqueue the task first? It would seem
> to me that it is far easier for cancel() to work out what to do if it knows
> that none of the tasks in the group can still execute.

my notion here is that if the Callable is given to an Executor, then cancel()
is not called directly.
rather, interrupt() or unqueue() is called on the Executor (or on a handle
provided by the Executor such as a ControllableFuture).

after handing it to Executor, then interrupt() or unqueue() will call cancel().
since the Executor is doing it, it can make sure that apropriate synchronization
is done. (we might consider making it optional whether cancel() is called;
right now in my prototype code, both will call cancel(). also if the task
is not yet running, a call to interrupt() will instead do an unqueue()).

the person implementing cancel() for some Callable should write it so that
it can be called at any time. An example might be this:

class MyCallable implements Callable {
   Object handle_ = null;
   Object result_ = null;
   Object call() {
      handle_ = get_request_handle(...); // won't block
      try {result_ = wait_handle(handle_);} // might block, assume non null return
      catch (InterruptedException e) {
          System.out.println("i've been interruted");
         throw e;
      }
   }

   boolean cancel() {
      if (handle_ == null) return false; // not run yet
      if (result_ != null) return false; // already done
      if (cancel_request(handle_)) return true;
      else {System.out.println("cancellation failed!"); return false;}
   }
}

-mda