Why do I require a `wl_event_loop_add_idle` in creating a fork-exec wayland client

Sichem Zhou sichem.zh at gmail.com
Fri Aug 3 12:22:27 UTC 2018


Hi Markus,

I am using the same parameters for socketpair. Here is my actual code:


static int
exec_wayland_client(const char *path, int fd)
{
        if (seteuid(getuid()) == -1) {
                return -1;
        }
        //unblock all the signals

        sigset_t allsignals;
        sigfillset(&allsignals);
        sigprocmask(SIG_UNBLOCK, &allsignals, NULL);

        char sn[10];
        int clientid = dup(fd);
        snprintf(sn, sizeof(sn), "%d", clientid);
        setenv("WAYLAND_SOCKET", sn, 1);

        if (execlp(path, path, NULL) == -1) {
                weston_log("failed to execute the client %s\n", path);
                close(clientid);
                return -1;
        }
        return 0;
}

struct wl_client *
tw_launch_client(struct weston_compositor *ec, const char *path)
{
        int sv[2];
        pid_t pid;
        struct wl_client *client;
        if (os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, sv)) {
                weston_log("taiwins_client launch: "
                           "failed to create the socket for client `%s`\n",
                           path);
                return NULL;
        }

        pid = fork();
        if (pid == -1) {
                close(sv[0]);
                close(sv[1]);
                weston_log("taiwins_client launch: "
                           "failed to create the process, `%s`\n",
                        path);
                return NULL;
        }
        if (pid == 0) {
                //you should close the server end
                close(sv[0]);
                //find a way to exec the child with sv[0];
                //okay, this is basically setting the environment variables
                exec_wayland_client(path, sv[1]);
                //replace this
                exit(-1);
        }
        //for parents, we don't need socket[1]
        close(sv[1]);
        //wayland client launch setup: by leveraging the UNIX
        //socketpair functions. when the socket pair is created. The
        client = wl_client_create(ec->wl_display, sv[0]);
        if (!client) {
                //this can't be happening, but housework need to be done
                close(sv[0]);
                weston_log("taiwins_client launch: "
                           "failed to create wl_client for %s", path);
                return NULL;
        }
        //now we some probably need to add signal on the server side
        return client;
}

The actual reason which causes the hang up in the process I haven't figured
out. But I guess it may be related the who is polling first, client or
server.

Regards,
Sichem

On Thu, Aug 2, 2018 at 11:46 PM, Markus Ongyerth <wl at ongy.net> wrote:

> On 2018/7月/11 09:42, Sichem Zhou wrote:
> > Hi All,
> >
> > I have a question related to the wl_client creation in the compositor. I
> > followed these step like weston did:
> >
> > 1. create socketpair.
> > 2. fork a process and close `socket[0]` in child, close `socket[1]` in in
> > parent process.
> > 3. set the `WAYLAND_SOCKET` to `socket[1]`.
> > 4. exec the program.
>
> You seem to be missing a few steps here. They probably exist in your code,
> but
> it suggests to me that you might cause this somewhere else.
> I have code [1] that doesn't rely on any idle dispatching and worked fine
> so
> far.
>
> This includes a single step in the compositor:
> 3. Set up client with wl_display_create_client
>
>
> Just lookking at my code, I see and remember that I'm using AF_UNIX and
> SOCK_STREAM arguments for the socketpair, which ones do you pass to yours?
>
>
> [1] https://github.com/waymonad/waymonad/blob/master/src/
> Waymonad/Actions/Spawn.hs#L181
>
> ongy
>
> >
> > I found out if I do this directly both compositor and client will stuck
> in
> > the eventloop. It seems the compositor is stuck in the
> > `wl_display_flush_clients` and client is stuck in
> `wl_event_queue_dispatch`
> > and internally stuck in the epoll.  So I think both compositor and client
> > were waiting each other for some update.
> >
> > Then I found out that  I need to pack the code in a
> > `wl_event_loop_idle_func_t` and add it to the event_loop. But I am
> couldn't
> > figure out why did the compositor stuck in the first place and why did
> the
> > wl_event_loop_add_idle helped.
> >
> > Thanks very much.
> > SZ
>
> > _______________________________________________
> > wayland-devel mailing list
> > wayland-devel at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/wayland-devel
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20180803/6e087f16/attachment.html>


More information about the wayland-devel mailing list