
condition_signal(+Handle, +Mode)

   Signal a condition on a handle

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

Type
   Engines and Threads

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 --- Handle or Mode is not instantiated.
     5 --- Handle is not a handle.
     5 --- Mode is not an atom.
     6 --- Mode is an atom other than 'all' or 'one'.
   141 --- Handle refers to an object that does not support this operation.
   170 --- 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
