FFI, signals and exceptions

Simon Marlow marlowsd at gmail.com
Fri Aug 27 04:05:46 EDT 2010

On 26/08/2010 18:20, Edward Z. Yang wrote:
> Ahem, the logic in that last iteration was not quite correct.
> Here is the more correct version:
>      case BlockedOnCCall:
>      case BlockedOnCCall_NoUnblockExc:
>      {
>          Task *task = NULL;
>          if (!target->bound) {
>              // walk all_tasks to find the correct worker thread
>              for (task = all_tasks; task != NULL; task = task->all_link) {
>                  if (task->incall->suspended_tso == target) {
>                      break;
>                  }
>              }
>              if (task != NULL) {
>                  raiseAsync(cap, target, msg->exception, rtsFalse, NULL);
>                  pthread_cancel(task->id);
>                  task->cap = NULL;
>                  task->stopped = rtsTrue;
>                  return THROWTO_SUCCESS;
>              }
>          }
> #endif
>          blockedThrowTo(cap,target,msg);
>          return THROWTO_BLOCKED;
>      }
> Is a lock necessary to walk all_tasks?

You should walk cap->suspended_ccalls instead, no lock is required for that.

For stress testing, you want to construct an example that has lots of 
threads making foreign cals and other threads calling throwTo to 
interrupt them.

So this is a proof of concept, and it seems to work  - great!  If we're 
going to do this for real, then there's a few more things we need:

  - we should probably annotate foreign calls with "interruptible" if
    they can be interrupted.  That entails some changes to GHC, and
    to the way foreign calls get compiled: we'll need to pass an extra
    flag to suspendThread().

  - the Task that has been cancelled needs to clean itself up

  - can we do this on Windows at all?  It woud be even more useful
    on Windows where blocking I/O is done by foreign calls, and is
    currently non-interruptible.

  - bound threads: we can't cancel a bound thread, because then there's
    no way to return to the caller (a bound thread results from a call
    to a Haskell function from C).  This makes the programming model
    slightly unpleasant, because a foreign call will only be
    interruptble when called in certan contexts, but I don't know what
    to do about that.


More information about the Glasgow-haskell-users mailing list