[systemd-devel] sd_event_run

Tom Gundersen teg at jklm.no
Fri Mar 13 10:10:17 PDT 2015


On Fri, Mar 13, 2015 at 4:35 PM, Zbigniew Jędrzejewski-Szmek
<zbyszek at in.waw.pl> wrote:
> you added sd_event_run a while ago:
>
> commit c45a5a74465a39280b855f9d720b2ab4779a47fa
> Author: Tom Gundersen <teg at jklm.no>
> Date:   Fri Aug 15 18:49:29 2014 +0200
>
>     sd-event: split run into prepare/wait/dispatch
>
>     This will allow sd-event to be integrated into an external event loop, which
>     in turn will allow (say) glib-based applications to use our various libraries,
>     without manually integrating each of them (bus, rtnl, dhcp, ...).
>
>     The external event-loop should integrate sd-event int he following way:
>
>     Every iteration must start with a call to sd_event_prepare(), which will
>     return 0 if no event sources are ready to be processed, a positive value if
>     they are and a negative value on error. sd_event_prepare() may only be called
>     following sd_event_dispatch(); a call to sd_event_wait() indicating that no
>     sources are ready to be dispatched; or a failed call to sd_event_dispatch() or
>     sd_event_wait().
>
>     A successful call to sd_event_prepare() indicating that no event sources are
>     ready to be dispatched must be followed by a call to sd_event_wait(),
>     which will return 0 if it timed out without event sources being ready to
>     be processed, a negative value on error and a positive value otherwise.
>     sd_event_wait() may only be called following a successful call to
>     sd_event_prepare() indicating that no event sources are ready to be dispatched.
>
>     If sd_event_wait() indicates that some events sources are ready to be
>     dispatched, it must be followed by a call to sd_event_dispatch(). This
>     is the only time sd_event_dispatch() may be called.
>
> +_public_ int sd_event_run(sd_event *e, uint64_t timeout) {
> +        int r;
> +
> +        assert_return(e, -EINVAL);
> +        assert_return(!event_pid_changed(e), -ECHILD);
> +        assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
> +        assert_return(e->state == SD_EVENT_PASSIVE, -EBUSY);
> +
> +        r = sd_event_prepare(e);
> +        if (r > 0)
> +                return sd_event_dispatch(e);
> +        else if (r < 0)
> +                return r;
> +
> +        r = sd_event_wait(e, timeout);
> +        if (r > 0)
> +                return sd_event_dispatch(e);
> +        else
> +                return r;
> +}
>
> Your commit description is almost ready to be turned into a man page, but there
> a hiccup. According to the last paragraph of the commit message, sd_event_dispatch may
> only be called after sd_event_wait(). This contradict the code in sd_event_run().
> (sd_event_dispatch calls sd_event_wait internally, but the user does not know
> this). Can you clarify the intended rules?

Indeed. Perhaps the best way to explain it is to look at the states:

        SD_EVENT_PASSIVE,
        SD_EVENT_PREPARED,
        SD_EVENT_PENDING,
        SD_EVENT_FINISHED,

*) sd_event starts off in SD_EVENT_PASSIVE

*) sd_event_prepare() may only be called from SD_EVENT_PASSIVE. If a
failure occurs a negative value is returned and the state remains
SD_EVENT_PASSIVE. If there are pending events a positive value is
returned and the state changes to SD_EVENT_PENDING. Otherwise, 0 is
returned and the state changes to SD_EVENT_PREPARED.

*) sd_event_wait() may only be called from SD_EVENT_PREPARED. If there
are pending events it returns a positive value and enters
SD_EVENT_PENDING. Otherwise, the state is is changed back to
SD_EVENT_PASSIVE and 0 is returned if there are no pending events and
a negative value is returned on error.

*) sd_event_dispatch() may only be called from SD_EVENT_PENDING. When
it returns the state has changed to SD_EVENT_PASSIVE or
SD_EVENT_FINISHED.

Does that make sense?

Cheers,

Tom


More information about the systemd-devel mailing list