[ 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):

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

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