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 <w...@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@lists.freedesktop.org > > https://lists.freedesktop.org/mailman/listinfo/wayland-devel > >
_______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel