[ Engines and Threads | Reference Manual | Alphabetic Index ]

# yield(+ToParent, -FromParent)

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

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

## 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