Resolution (workaround) for Issue 82
Now FDA is properly aborted if it is waiting for a channel to get to a specific value ...
This commit is contained in:
@@ -48,6 +48,9 @@ public class ChannelAccessCondition<E> implements Action {
|
||||
|
||||
private final Long timeout;
|
||||
|
||||
private volatile boolean abort = false;
|
||||
private volatile Thread waitT = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param channelName Name of the channel to set the value
|
||||
@@ -93,11 +96,20 @@ public class ChannelAccessCondition<E> implements Action {
|
||||
*/
|
||||
@Override
|
||||
public void execute() throws InterruptedException {
|
||||
abort=false;
|
||||
logger.finest("Checking channel "+channel.getName()+" for value "+expectedValue+" [timeout: "+timeout+"]" );
|
||||
try{
|
||||
waitT = Thread.currentThread();
|
||||
channel.waitForValue(expectedValue, timeout); // Workaround use 10seconds default set timeout to check several times whether the channel has reached the value
|
||||
} catch (CAException e) {
|
||||
throw new RuntimeException("Channel [name:"+channel.getName()+"] did not reach expected value "+expectedValue+" ", e);
|
||||
} catch(InterruptedException e){
|
||||
if(!abort){
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
finally{
|
||||
waitT=null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +118,10 @@ public class ChannelAccessCondition<E> implements Action {
|
||||
*/
|
||||
@Override
|
||||
public void abort() {
|
||||
// This action cannot be aborted, therefore this method is not implemented
|
||||
abort=true;
|
||||
if(waitT!=null){
|
||||
waitT.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -112,7 +112,8 @@ public class ActorSensorLoop implements ActionLoop {
|
||||
*/
|
||||
private Guard guard = null;
|
||||
|
||||
private boolean loop = false;
|
||||
private volatile boolean loop = false;
|
||||
private volatile boolean abort = false;
|
||||
|
||||
private final boolean zigZag;
|
||||
|
||||
@@ -168,6 +169,8 @@ public class ActorSensorLoop implements ActionLoop {
|
||||
*/
|
||||
@Override
|
||||
public void execute() throws InterruptedException {
|
||||
abort = false;
|
||||
|
||||
/**
|
||||
* Thread pool for parallel execution of tasks
|
||||
*/
|
||||
@@ -224,6 +227,10 @@ public class ActorSensorLoop implements ActionLoop {
|
||||
action.execute();
|
||||
}
|
||||
|
||||
if(abort){ // End loop if abort was issued
|
||||
break;
|
||||
}
|
||||
|
||||
// Set actors
|
||||
// for(Actor actor: actors){
|
||||
// actor.set();
|
||||
@@ -241,6 +248,10 @@ public class ActorSensorLoop implements ActionLoop {
|
||||
for(Action action: postActorActions){
|
||||
action.execute();
|
||||
}
|
||||
|
||||
if(abort){ // End loop if abort was issued
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -276,6 +287,10 @@ public class ActorSensorLoop implements ActionLoop {
|
||||
action.execute();
|
||||
}
|
||||
|
||||
if(abort){ // End loop if abort was issued
|
||||
break;
|
||||
}
|
||||
|
||||
// Read sensors
|
||||
DataMessage message = new DataMessage();
|
||||
for(Sensor sensor: sensors){
|
||||
@@ -290,6 +305,10 @@ public class ActorSensorLoop implements ActionLoop {
|
||||
action.execute();
|
||||
}
|
||||
|
||||
if(abort){ // End loop if abort was issued
|
||||
break;
|
||||
}
|
||||
|
||||
// Check guard if one is registered
|
||||
if(guard!=null){
|
||||
guardOK=guard.check();
|
||||
@@ -333,6 +352,7 @@ public class ActorSensorLoop implements ActionLoop {
|
||||
*/
|
||||
@Override
|
||||
public void abort(){
|
||||
abort = true;
|
||||
loop = false;
|
||||
|
||||
// To abort all wait actions interrupt this thread
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
*
|
||||
* Copyright 2011 Paul Scherrer Institute. All rights reserved.
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation, either version 3 of the License, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but without any
|
||||
* warranty; without even the implied warranty of merchantability or fitness for
|
||||
* a particular purpose. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this code. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package ch.psi.fda.aq;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author ebner
|
||||
*
|
||||
*/
|
||||
public class AcquisitionMainTest {
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws java.lang.Exception
|
||||
*/
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test method for {@link ch.psi.fda.aq.AcquisitionMain#main(java.lang.String[])}.
|
||||
*/
|
||||
@Ignore
|
||||
@Test
|
||||
public void testMain() {
|
||||
System.setProperty("ch.psi.fda.home","src/test/resources/home");
|
||||
AcquisitionMain.main(new String[]{"src/test/resources/home/scans/templates/scan1d-waitError.xml"});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -174,5 +174,37 @@ public class ChannelAccessConditionTest {
|
||||
fail("Action did not return although the value was reached");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to ensure that the abort function is working correctly
|
||||
* @throws CAException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
@Test
|
||||
public void testWaitAbort() throws CAException, InterruptedException {
|
||||
final ChannelAccessCondition<Integer> action = new ChannelAccessCondition<Integer>(TestChannels.BINARY_OUT, 1, 10000l);
|
||||
final ChannelBean<Integer> channel = ChannelBeanFactory.getFactory().createChannelBean(Integer.class, TestChannels.BINARY_OUT, false);
|
||||
|
||||
Thread t = new Thread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
logger.info("Send abort ...");
|
||||
action.abort();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Set wait channel to 0
|
||||
channel.setValue(0);
|
||||
|
||||
t.start();
|
||||
action.execute(); // timeouts after 10 seconds
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user