Re: [eclipse-users] Java-ECLiPSe: How to terminate execution of EclipseConnection.rpc(...) ?

From: Joachim Schimpf (Independent Contractor) <jschimpf_at_cisco.com>
Date: Fri, 27 Apr 2007 12:03:26 +0100
Christian Pfaller wrote:
> I'm calling ECLiPSe via the Java-ECLiPSe interface and I want to give
> the user the possibility to abort the execution of the rpc(...) call to
> ECLiPSe. Thus I'd like to achieve pretty the same behavior as pressing
> the "interrupt" button in TkEclipse.
> 
> I was thinking about having to Java Threads: One which executes the
> rpc(...) method from EclipseConnection and the other Thread which
> listens, if the user wants to abort execution.
> 
> They onl solution I see so far is to use Thread.stop() ... but since Sun
> doesn't recommend this at all ("... inherently unsafe ...") I'd prefer
> to avoid it. (And Thread.stop() doesn't always show the desired effect).
> 
> The nice way of terminating threads - using the Thread.interrupt()
> method and waiting for an InteruptExeception seems to be not supported
> by the rpc(...) methods of ECLiPSe. So, is there any other safe way to
> terminate rpc(...) ? Maybe someone could post some example code.
> 
> I'm using the EmbeddedEclipse engine. I'm not sure if this could be
> easier solved by OutOfProcessEclipse or RemoteEclipse but in any case
> I'm quite unsure what's a good way of terminating the call to ECLiPSe.


You can do that with OutOfProcessEclipse and RemoteEclipse variants
by opening an asynchronous queue (see 
http://www.eclipse-clp.ord/doc/embedding/embroot047.html),
and let the queue handler on the ECLiPSe side raise an 'abort' event.

I attach some corresponding Java code from our test suite.  It looks
a bit lengthy, but all it does is to create the queue and set up a 
handler from the ECLiPSe side:

     event_create(post_events_from_stream(aeq_test), [defers],
                  Event)@sepia_kernel,
     peer_queue_create(aeq_test, host, async, bidirect, Event)

and from the Java side the interrupting thread simply writes an EXDR
"abort" to this queue, which the ECLiPSe-side handler then turns into
an abort-event.

You can also look at the source code of the ECLiPSe toplevel
(<eclipsedir>/pl/toplevel.pl, look for gui_interrupt_request)
to see similar code used for the tkeclipse interrupt button.


   class AsyncQueuePostEventTest extends EclipseConnectionTest
   {
     String setTestName(){return("Async queue event posting test");}
     EclipseConnection tested_eclipse;
     AsyncEclipseQueue aeq;

     AsyncQueuePostEventTest(EclipseConnection subjectEclipse, String 
subjectEclipseName)
     {
       super(subjectEclipse, subjectEclipseName);
     }

     public void EventPoster() {
	  try{
	      Thread.sleep(1000);
	      EXDROutputStream eos = new EXDROutputStream(aeq.getOutputStream());
	      eos.write("abort");
	      eos.flush();
	  }
	  catch(Exception e)
	  {
	    System.out.println("Exception: " + e.toString() );
	    e.printStackTrace();
	  }
     }

     boolean test(EclipseConnection eclipse)
     {
       // create queue
       String aeqName = "aeq_test";
       try {
	eclipse.rpc(
	      "event_create(post_events_from_stream("+aeqName+"), [defers], 
Event)@sepia_kernel,"+
	      "peer_queue_create("+aeqName+", '"+
		  eclipse.getPeerName().functor()+"',"+
		  "async, bidirect, Event)");
	aeq = eclipse.getAsyncEclipseQueue(aeqName);
       }
       catch(Exception e)
       {
	System.out.println("Exception: " + e.toString() );
	e.printStackTrace();
	return(false);
       }

       // create event posting thread
       tested_eclipse = eclipse;
       Runnable runEventPoster = new Runnable() {
	    public void run() { EventPoster(); }
	};
       (new Thread(runEventPoster, "Event Poster")).start();

       // run rpc
       try
       {
         eclipse.rpc("between(1,5,1,_),sleep(1),fail ; true");
         return(false);
       }
       catch(Throw t)
       {
	// expected result!
       }
       catch(Exception e)
       {
  	System.out.println("Exception: " + e.toString() );
         e.printStackTrace();
         return(false);
       }

       try
       {
	eclipse.rpc("peer_queue_close("+aeqName+")");
       }
       catch(Exception e)
       {
  	System.out.println("Exception: " + e.toString() );
         e.printStackTrace();
         return(false);
       }
       return true;
     }
   }



-- Joachim
Received on Fri Apr 27 2007 - 12:03:45 CEST

This archive was generated by hypermail 2.2.0 : Thu Feb 02 2012 - 02:31:58 CET