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:
ebner
2011-10-25 13:53:12 +02:00
parent 4b61d1bcac
commit c95e46a8e6
4 changed files with 125 additions and 2 deletions
@@ -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
}
}