next up previous 61
Next: Behaviour of the parameter system
Up: ADAM Guide to Writing Instrumentation Tasks
Previous: Receipt of messages from other tasks


Cancelling actions

It is possible to cancel an action which is in a wait state. Here is a simple example.

interface timer
   action WAIT
      obey
      endobey
      cancel
      endcancel
   endaction
endinterface

      SUBROUTINE TIMER ( STATUS )
      IMPLICIT NONE
      INCLUDE 'SAE_PAR'
      INCLUDE 'ACT_ERR'
      INCLUDE 'ADAMDEFNS'
      INTEGER STATUS
      INTEGER SEQ
      INTEGER CONTEXT

      IF ( STATUS .NE. SAI__OK ) RETURN
      CALL TASK_GET_CONTEXT ( CONTEXT, STATUS )
      IF ( CONTEXT .EQ. OBEY ) THEN
         CALL TASK_GET_SEQ ( SEQ, STATUS )
         IF ( SEQ .EQ. 0 ) THEN
            CALL TASK_PUT_DELAY ( 10000, STATUS )
            CALL TASK_PUT_REQUEST ( ACT__WAIT, STATUS )
         ELSE
            CALL MSG_OUT ( ' ', 'finished', STATUS )
         ENDIF
      ELSE IF ( CONTEXT .EQ. CANCEL ) THEN
         CALL MSG_OUT ( ' ', 'I was cancelled', STATUS )
         CALL TASK_PUT_REQUEST ( ACT__CANCEL, STATUS )
      ENDIF
      END

Note the CANCEL declaration in the interface file. This example is exercised by

ICL> send timer obey wait
ICL> send timer cancel wait

It is possible to write the application such that CANCEL modifies the behaviour of the rescheduling action rather than terminating it.

interface timer
   parameter CANTIME
      type '_INTEGER'
   endparameter
   action WAIT
      obey
      endobey
      cancel needs CANTIME
      endcancel
   endaction
endinterface

      SUBROUTINE TIMER ( STATUS )
      IMPLICIT NONE
      INCLUDE 'SAE_PAR'
      INCLUDE 'ACT_ERR'
      INCLUDE 'ADAMDEFNS'
      INTEGER STATUS
      INTEGER SEQ
      INTEGER CONTEXT
      INTEGER STATE
      SAVE STATE, TIME

      IF ( STATUS .NE. SAI__OK ) RETURN
      CALL TASK_GET_CONTEXT ( CONTEXT, STATUS )
      IF ( CONTEXT .EQ. OBEY ) THEN
         CALL TASK_GET_SEQ ( SEQ, STATUS )
         IF ( SEQ .EQ. 0 ) THEN
            STATE = 0
            CALL TASK_PUT_DELAY ( 500, STATUS )
            CALL TASK_PUT_REQUEST ( ACT__WAIT, STATUS )
         ELSE
            IF ( STATE .EQ. 0 ) THEN
*            Normal reschedule
               CALL TASK_PUT_DELAY ( 500, STATUS )
               CALL MSG_OUT ( ' ', 'default timer', STATUS )
               CALL TASK_PUT_REQUEST ( ACT__WAIT, STATUS )
            ELSE
*            Rescheduling after CANCEL
               CALL TASK_PUT_DELAY ( TIME, STATUS )
               CALL MSG_OUT ( ' ', 'altered timer', STATUS )
               CALL TASK_PUT_REQUEST ( ACT__WAIT, STATUS )
            ENDIF
         ENDIF
      ELSE IF ( CONTEXT .EQ. CANCEL ) THEN
         STATE = 1
         CALL PAR_GET0I ( 'CANTIME', TIME, STATUS )
         CALL TASK_PUT_DELAY ( TIME, STATUS )
         CALL MSG_OUT ( ' ', 'timer changed', STATUS )
         CALL TASK_PUT_REQUEST ( ACT__WAIT, STATUS )
      ENDIF
      END

Then:

ICL> send timer obey wait
ICL> send timer cancel wait 10000

will cause the task to start rescheduling at 0.5sec intervals, but then switch to rescheduling at 10sec intervals. In this particular example the action never terminates.

An example of sending a CANCEL to a task which is controlling a subsidiary task is given in Appendix [*].



next up previous 61
Next: Behaviour of the parameter system
Up: ADAM Guide to Writing Instrumentation Tasks
Previous: Receipt of messages from other tasks

ADAM Guide to Writing Instrumentation Tasks
Starlink User Note 134
B D Kelly
A J Chipperfield

30 March 1992
E-mail:ussc@star.rl.ac.uk

Copyright © 2000 Council for the Central Laboratory of the Research Councils