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