
yield(+ToParent, -FromParent)

   Stop the running engine in the yielded-state, and wait for resume

Arguments
   ToParent            A term to be passed to the parent.
   FromParent          A variable to be unified with term from parent.

Type
   Engines and Threads

Description

   All ECLiPSe code is executed by an ECLiPSe engine.  This engine can
   be invoked from a parent program, which is either in a different language
   (C/C++, Tcl, Java), or is itself an ECLiPSe program.  In either case,
   the interaction between the ECLiPSe engine and the parent execution
   follows a resume-yield model of control flow: the parent execution
   transfers control to the engine via a 'resume' operation, and the engine
   returns control via a 'yield' operation.  There are implicit yield
   operations (such as when the engine execution succeeds, fails or aborts),
   but the yield/2 predicate provides an explicit way of transferring control.

   An engine that executes the yield/2 predicate stops executing, enters
   the yielded-state, and waits until it is resumed again.

   Data can be passed both ways: the ToParent argument is passed from
   the engine to a parent on yielding, the FromParent argument receives
   a term from the parent on resumption.


Synchronous Operation

   Synchronous operation means that the engine was resumed via the
   engine_resume/3 predicate (if the resumer is ECLiPSe code), or one
   of the corresponding primitives in one of the foreign language
   interfaces (e.g. ec_resume()).  In response to a yield/2, the
   resume-primitive returns, and the status code yielded(ToParent)
   is passed from the yielding engine to its resumer.

   If the engine is resumed again later (e.g. with another call to
   engine_resume/3), the yield/2 predicate inside the engine succeeds,
   and engine execution continues.  The second argument of engine_resume/3
   (FromParent) is passed from the resumer to the engine, and unified with
   the second argument of yield/2 before engine execution continues.


Asynchronous Operation

   Asynchronous operation means that the engine was resumed via the
   engine_resume_thread/2 predicate (if the resumer is ECLiPSe code),
   or one of the corresponding primitives in one of the foreign language
   interfaces (e.g. ec_resume_async()).  In  this case, the engine runs
   in its own thread, and in response to a yield/2 another thread can
   join the engine (engine_join/3), pick up the yielded(ToParent) status,
   and possibly resume the engine again later.



Modes and Determinism
   yield(+, -) is det

Examples
   
% Communication between engines (synchronous)

    ?- engine_create(E, []),
       engine_resume(E, (
                yield(message_to_parent,From),
                writeln(received(From))
            ), S1),
       engine_resume(E, message_from_parent, S2).

    received(message_from_parent)

    E = $&(engine,"376oe7")
    S1 = yielded(message_to_parent)
    S2 = true
    Yes (0.00s cpu)


% Communication between engines (asynchronous)

    ?- engine_create(E, []),
       engine_resume_thread(E, (
                yield(message_to_parent,From),
                writeln(received(From))
            )),
       engine_join(E, block, S1),
       engine_resume_thread(E, message_from_parent),
       engine_join(E, block, S2).

    received(message_from_parent)

    E = $&(engine,"376oe7")
    S1 = yielded(message_to_parent)
    S2 = true
    Yes (0.00s cpu)



% Embedding situation: ECLiPSe server code

    start_server :-
        eclipse_server(dummy).

    eclipse_server(PrevResult) :-
        yield(PrevResult, Request),
        process_request(Request, NewResult),
        eclipse_server(NewResult).


    // C++ client code
    ec_init();
    post_goal("start_server");
    if (EC_resume() == EC_yield)
    {
        for(;;)
        {
            // create a request
            ...
            if (EC_resume(request, result) != EC_yield);
                break;
            ...
            // use the result
        }
    }


See Also
   engine_resume / 3, engine_resume_thread / 2, engine_join / 3, get_engine_property / 3
