/*=====================================================================*/
/*    serrano/prgm/project/bigloo/fthread/src/BglAsyncThunk.java       */
/*    -------------------------------------------------------------    */
/*    Author      :  Manuel Serrano                                    */
/*    Creation    :  Mon Feb 11 13:45:20 2002                          */
/*    Last change :  Sat Oct 19 15:20:28 2002 (serrano)                */
/*    Copyright   :  2002 Manuel Serrano                               */
/*    -------------------------------------------------------------    */
/*    A class implementing asynchronous thread. An asynchronous thread */
/*    is implemented by the means of a Java thread that permantenly    */
/*    execute a thunk.                                                 */
/*=====================================================================*/
using System;
using System.Threading;
using bigloo;

namespace bigloo.fairthread
{
  /*---------------------------------------------------------------------*/
  /*    BglAsyncThunk                                                    */
  /*---------------------------------------------------------------------*/
  public class BglAsync {

    private procedure thunk;
    private Object id;
    private BglThread scdl;

    // The thread associated with this object
    private readonly Thread thread;

    // public constructor
    public BglAsync( BglThread s, procedure proc, Object i ) {
      scdl = s;
      thunk = proc;
      id = i;
      start();
      thread= new Thread( new ThreadStart( run ) );
    }

    // The thread entry-point
    public void run() {
      try {
        thunk.funcall0();
      } catch( Exception e ) {
        try {
          foreign.internalerror( e );
        } catch( Exception ) {
          Environment.Exit( 1 );
        }
      }
    }

    // Starts the thread
    public void start() {
      thread.Start();
    }

    // Scheduler wait for an asynchronous event. This function must
    // always be called within the dynamic extent of a bglasync_synchronize
    public static void scheduler_wait( BglThread scdl ) {
      try {
        Monitor.Wait( scdl );
      } catch( Exception e ) {
        try {
          foreign.internalerror( e );
        } catch( Exception ) {
          Environment.Exit( 1 );
        }
      }
    }

    // Notify a Scheduler of an asynchronous event. This function must
    // always be called within the dynamic extent of a bglasync_synchronize
    public static void scheduler_notify( BglThread scdl ) {
      Monitor.Pulse( scdl );
    }

    // synchronized block
    public static Object synchronize( BglThread scdl, procedure proc ) {
      lock( scdl ) {
        return proc.funcall0();
      }
    }
  }
}

