since 2.0.0

The 'blocking' keyword allows omission of a reply statement from an action statement and supresses the implicit void reply performed after the last statement in an action statement. An action statement in another port in-event should perform the reply statement for the blocked port. Thus, time and value of a blocked port reply depend on another in-event. The keyword 'blocking' is allowed to appear once in the path of statements prefixing an action statement.

Only 'provides' ports are affected by 'blocking'. A call of a provided port in-event will not return before a reply statement is performed for that port.

Guard expressions or 'on event' is commutative with respect to blocking. If 'blocking' appears before a guard or 'on event' it applies to the action statement after the guard or 'on event'.

'blocking' may only be used in components with a single 'provides' port. This limitation may be lifted in a future release.
Systems containing 'blocking' component instances must be contained in a Using a Thread-safe shell.

Syntax

on event: blocking action-statement; (1)
blocking on event: action-statement; (2)
on event: blocking [guard] action-statement; (3)
on event: {blocking [guard] action-statement1; [guard] action-statement2;} (4)

Explanation:

for (2): The 'blocking' keyword applies to the action-statement following 'on event:'. This form is semantically equivalent to 1).

for (3): The 'blocking' keyword applies to the action-statement following [guard]. This form is semantically equivalent to "on event: [guard] blocking action-statement;"

for (4): The 'blocking' keyword applies to action-statement1. It does NOT apply to action-statement2.

Examples

Thread signalling

Component CA illustrates the use of 'blocking' to postpone thread return. An 'on event' on a different port performs the 'reply' statement for the blocked port.

The action statement in 'on pp.request_value' is marked as 'blocking' and does not contain a reply statement. A thread calling pp.request_reply blocks after action statement 'rp.request()'. The blocked thread returns when the action statement for 'on rp.accept' or 'on rp.reject' have been performed.

interface IBlockingRequest
{
  in bool request_value();
  in void request_event();
  out void accept();
  out void reject();

  behaviour
  {
    on request_value: reply(true);
    on request_value: reply(false);
    on request_event: accept;
    on request_event: reject;
  }
}

interface INonBlockingRequest
{
  in void request();
  out void accept();
  out void reject();

  behaviour
  {
    bool is_considering = false;

    on request: is_considering = true;
    [is_considering] on inevitable: {accept; is_considering = false;}
    [is_considering] on inevitable: {reject; is_considering = false;}
  }
}

component CA
{
  provides IBlockingRequest pp;
  requires INonBlockingRequest rp;

  behaviour
  {
    bool is_valued_event = true;

    on pp.request_value(): blocking {is_valued_event = true; rp.request();}
    blocking on pp.request_event(): {is_valued_event = false; rp.request();}

    [is_valued_event] on rp.accept(): pp.reply(true);
    [!is_valued_event] on rp.accept(): {pp.accept(); pp.reply();}

    [is_valued_event] on rp.reject(): {bool b = false; pp.reply(b);}
    [!is_valued_event] on rp.reject(): {pp.reject(); pp.reply();}
  }
}

See also: