<div dir="ltr"><div>Hi Markus,</div><div><br></div><div>I am using the same parameters for socketpair. Here is my actual code:</div><div><br></div><div><br></div><div>static int<br>exec_wayland_client(const char *path, int fd)<br>{<br>        if (seteuid(getuid()) == -1) {<br>                return -1;<br>        }<br>        //unblock all the signals<br><br>        sigset_t allsignals;<br>        sigfillset(&allsignals);<br>        sigprocmask(SIG_UNBLOCK, &allsignals, NULL);<br><br>        char sn[10];<br>        int clientid = dup(fd);<br>        snprintf(sn, sizeof(sn), "%d", clientid);<br>        setenv("WAYLAND_SOCKET", sn, 1);<br><br>        if (execlp(path, path, NULL) == -1) {<br>                weston_log("failed to execute the client %s\n", path);<br>                close(clientid);<br>                return -1;</div><div>        }<br>        return 0;<br>}<br></div><div><br></div><div>struct wl_client *<br>tw_launch_client(struct weston_compositor *ec, const char *path)<br>{<br>        int sv[2];<br>        pid_t pid;<br>        struct wl_client *client;<br>        if (os_socketpair_cloexec(AF_UNIX, SOCK_STREAM, 0, sv)) {<br>                weston_log("taiwins_client launch: "<br>                           "failed to create the socket for client `%s`\n",<br>                           path);<br>                return NULL;<br>        }<br><br>        pid = fork();<br>        if (pid == -1) {<br>                close(sv[0]);<br>                close(sv[1]);<br>                weston_log("taiwins_client launch: "<br>                           "failed to create the process, `%s`\n",<br>                        path);<br>                return NULL;<br>        }<br>        if (pid == 0) {<br>                //you should close the server end<br>                close(sv[0]);<br>                //find a way to exec the child with sv[0];<br>                //okay, this is basically setting the environment variables<br>                exec_wayland_client(path, sv[1]);<br>                //replace this<br>                exit(-1);<br>        }<br>        //for parents, we don't need socket[1]<br>        close(sv[1]);<br>        //wayland client launch setup: by leveraging the UNIX<br>        //socketpair functions. when the socket pair is created. The<br>        client = wl_client_create(ec->wl_display, sv[0]);<br>        if (!client) {<br>                //this can't be happening, but housework need to be done<br>                close(sv[0]);<br>                weston_log("taiwins_client launch: "<br>                           "failed to create wl_client for %s", path);<br>                return NULL;<br>        }<br>        //now we some probably need to add signal on the server side<br>        return client;<br>}</div><div><br></div><div>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.</div><div><br></div><div>Regards,</div><div>Sichem<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Aug 2, 2018 at 11:46 PM, Markus Ongyerth <span dir="ltr"><<a href="mailto:wl@ongy.net" target="_blank">wl@ongy.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 2018/7月/11 09:42, Sichem Zhou wrote:<br>
> Hi All,<br>
> <br>
> I have a question related to the wl_client creation in the compositor. I<br>
> followed these step like weston did:<br>
> <br>
> 1. create socketpair.<br>
> 2. fork a process and close `socket[0]` in child, close `socket[1]` in in<br>
> parent process.<br>
> 3. set the `WAYLAND_SOCKET` to `socket[1]`.<br>
> 4. exec the program.<br>
<br>
</span>You seem to be missing a few steps here. They probably exist in your code, but <br>
it suggests to me that you might cause this somewhere else.<br>
I have code [1] that doesn't rely on any idle dispatching and worked fine so <br>
far.<br>
<br>
This includes a single step in the compositor:<br>
3. Set up client with wl_display_create_client<br>
<br>
<br>
Just lookking at my code, I see and remember that I'm using AF_UNIX and <br>
SOCK_STREAM arguments for the socketpair, which ones do you pass to yours?<br>
<br>
<br>
[1] <a href="https://github.com/waymonad/waymonad/blob/master/src/Waymonad/Actions/Spawn.hs#L181" rel="noreferrer" target="_blank">https://github.com/waymonad/<wbr>waymonad/blob/master/src/<wbr>Waymonad/Actions/Spawn.hs#L181</a><br>
<br>
ongy<br>
<span class=""><br>
> <br>
> I found out if I do this directly both compositor and client will stuck in<br>
> the eventloop. It seems the compositor is stuck in the<br>
> `wl_display_flush_clients` and client is stuck in `wl_event_queue_dispatch`<br>
> and internally stuck in the epoll.  So I think both compositor and client<br>
> were waiting each other for some update.<br>
> <br>
> Then I found out that  I need to pack the code in a<br>
> `wl_event_loop_idle_func_t` and add it to the event_loop. But I am couldn't<br>
> figure out why did the compositor stuck in the first place and why did the<br>
> wl_event_loop_add_idle helped.<br>
> <br>
> Thanks very much.<br>
> SZ<br>
<br>
</span>> ______________________________<wbr>_________________<br>
> wayland-devel mailing list<br>
> <a href="mailto:wayland-devel@lists.freedesktop.org">wayland-devel@lists.<wbr>freedesktop.org</a><br>
> <a href="https://lists.freedesktop.org/mailman/listinfo/wayland-devel" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/wayland-devel</a><br>
<br>
</blockquote></div><br></div>