[ Engines and Threads | Reference Manual | Alphabetic Index ]

# condition_signal(+Handle, +Mode)

Signal a condition on a handle

Handle
  A handle for an object supporting condition signaling
Mode
  One of the atoms 'all' or 'one'

## Description

This is a low-level primitive that, together with condition_wait/2 and with_mutex/2, can be used to implement synchronization between concurrent threads.

The predicate unblocks one (or all) currently waiting invocations of condition_wait/2 on the given Handle.

The typical usage pattern is this:

            wait_for_something(Handle) :-
                with_mutex(Handle, wait_for_something_locked(Handle)).

                wait_for_something_locked(Handle) :-
                    ( test_for_something ->
                        true
                    ;
                        condition_wait(Handle, block),
                        wait_for_something_locked(Handle)
                    ).

            produce_something(Handle) :-
                with_mutex(Handle, produce_something_locked(Handle)).

                produce_something_locked(Handle) :-
                    make_something_true,
                    condition_signal(Handle, all).

The following object handles can be used for condition signaling (to obtain a handle from an object's alias name, use name_to_handle/3):

- stream handle
- shelf handle
- store handle
- bag handle
- record handle

Typically, condition_signal/2 is executed in a context where the Handle has been locked, i.e. inside with_mutex/2. This allows grouping operations on Handle and signaling on Handle into one atomic action (see produce_message/2 in the example). While condition_wait/2 waits, the Handle mutex is unlocked.

### Modes and Determinism

- condition_signal(+, +) is det

### Exceptions

(4) instantiation fault
  Handle or Mode is not instantiated.
(5) type error
  Handle is not a handle.
(5) type error
  Mode is not an atom.
(6) out of range
  Mode is an atom other than 'all' or 'one'.
(141) unimplemented functionality
  Handle refers to an object that does not support this operation.
(170) system interface error
  Operating system error.

## Examples

    % Basic example

        ?-  bag_create(Handle),
            engine_create(E, []),
            engine_resume_thread(E, (
                   with_mutex(Handle, condition_wait(Handle, block)),
                   writeln(condition_was_signaled)
               )),
            sleep(3),
            condition_signal(Handle, one).

        condition_was_signaled      % printed after 3 seconds

    % Example code for signaling on a record-object

        wait_for_message(Handle, Message) :-
            with_mutex(Handle, wait_for_message_locked(Handle, Message)).

            wait_for_message_locked(Handle, Message) :-
                ( erase(Handle, Message) ->
                    true
                ;
                    condition_wait(Handle, block),
                    wait_for_message_locked(Handle, Message)
                ).

        produce_message(Handle, Message) :-
            with_mutex(Handle, produce_message_locked(Handle, Message)).

            produce_message_locked(Handle, Message) :-
                recordz(Handle, Message),
                condition_signal(Handle, all).

    % Query using the above code

        ?-  record_create(Handle),
            engine_create(E, [thread]),
            engine_resume_thread(E, (
                    wait_for_message(Handle, Message),
                    writeln(thread_received_message(Message))
                )),
            sleep(3),
            produce_message(Handle, "hello from main").

        thread_received_message(hello from main)     % printed after 3 seconds

## See Also

is_handle / 2, condition_wait / 2, with_mutex / 2, name_to_handle / 3