
engine_join(+Engine, +Timeout, -Status)

   Wait for an engine to stop running, and return its status

Arguments
   Engine              An engine handle
   Timeout             Timeout in seconds (integer or float), or the atom 'block'
   Status              Output: engine status term

Type
   Engines and Threads

Description
    Waits for an (asynchronously resumed) engine to stop executing, then
    returns its status.  The status descriptors are the same as in
    get_engine_property/3 (except that 'running' does normally not occur).
    If the engine does not stop within Timeout seconds, the predicate fails.
    If the engine is already stopped at the time of the join, it succeeds
    immediately.

    It is an error if the engine is running, but was not resumed in its
    own thread (e.g. it was resumed using engine_resume/3 by another thread).
    Moreover, one cannot join an engine that is running in the same thread
    as the caller of engine_join/3.

    If multiple joins are waiting for the same engine, they will all
    succeed when the engine stops.  In this special case, some of these
    joins may return the status 'running'.

    If Timeout is the atom 'block', no timeout is used, the operation
    can block indefinitely, and never fails.

    Instead of waiting for an engine to finish, the engine can use the
    report_to option to eagerly send a notification when it finishes.
    Such a notification means that the engine is ready to be joined.

    NOTE:  While blocked in engine_join/3, a thread does not respond to
    posted event goals (e.g. from engine_post/2 or event_after/2).
    In order to keep the thread responsive, one can replace
    
        engine_join(E, block, S)
    
    by a functionally equivalent construct such as
    
        once (repeat, engine_join(E, 1, S))
    
    This lets engine_join/3 time out and restart every second, thus
    creating opportunities for the handling of posted events.


Modes and Determinism
   engine_join(+, +, -) is semidet

Fail Conditions
   Fails if timeout occurs before engine stops

Exceptions
     4 --- Engine or Timeout is not instantiated
     5 --- Engine is not an engine handle
     5 --- Timeout is neither integer, float, nor the atom 'block'
     6 --- Timeout is a negative number
   181 --- Engine running, but cannot be joined

Examples
   
    ?- engine_create(E, [thread]),
       engine_resume_thread(E, writeln(hello)),
       engine_join(E, block, Status).
    hello
    E = $&(engine,"376oe7")
    Status = true
    Yes (0.00s cpu)

    ?- engine_create(E, [thread]),
       engine_resume_thread(E, 1=2),
       engine_join(E, block, Status).
    E = $&(engine,"376oe7")
    Status = false
    Yes (0.00s cpu)

    ?- engine_create(E, [thread]),
       engine_resume_thread(E, yield(hello,_)),
       get_engine_property(E, status, Status1),
       engine_resume_thread(E, true),
       engine_join(E, block, Status2).
    E = $&(engine,"376oe7")
    Status1 = yielded(hello)
    Status2 = true
    Yes (0.00s cpu)

    ?- engine_create(E, [thread]),
       engine_resume_thread(E, (repeat,fail)),
       ( engine_join(E, 5, S) -> writeln(status=S) ; writeln(timeout) ).
    timeout

    E = $&(engine,"376oe7")
    S = S
    Yes (5.00s cpu)


See Also
   engine_create / 2, engine_resume_thread / 2, get_engine_property / 3
