From 4ff5e75c986b37c8540f90422d3231d2756a073b Mon Sep 17 00:00:00 2001 From: Rajendraprasad K J Date: Tue, 14 Feb 2023 10:04:35 +0530 Subject: simple-weston-client: Improve signal handling Currently signal handling is not properly done while listening for events on wayland socket. As a result process waits on poll() for idefinite time even after receiving signal. Modify poll() to accept signals while listening to events on wayland socket. Signed-off-by: Rajendraprasad K J --- .../src/simple-weston-client.c | 66 +++++++++++++++++----- 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/ivi-layermanagement-examples/simple-weston-client/src/simple-weston-client.c b/ivi-layermanagement-examples/simple-weston-client/src/simple-weston-client.c index a0632c7..fe3d1d0 100644 --- a/ivi-layermanagement-examples/simple-weston-client/src/simple-weston-client.c +++ b/ivi-layermanagement-examples/simple-weston-client/src/simple-weston-client.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -90,6 +91,7 @@ typedef struct _WaylandContext { int pipefd[2]; #endif uint8_t enable_cursor; + int signal_fd; }WaylandContextStruct; struct debug_stream { @@ -751,21 +753,39 @@ weston_dlt_thread_function(void *data) #endif static void -signal_int(int signum) +signal_int(int signal_fd) { + struct signalfd_siginfo fdsi; + + if (read(signal_fd, &fdsi, sizeof(fdsi)) != sizeof(fdsi)) { + fprintf(stderr, "reading signalfd failed: %s\n", + strerror(errno)); + return; + } + + fprintf(stderr, "simple-weston-client: caught signal %d \n", + fdsi.ssi_signo); + running = 0; } static int -display_poll(struct wl_display *display, short int events) +display_poll(struct wl_display *display, int signal_fd, + short int events) { int ret; - struct pollfd pfd[1]; + struct pollfd pfd[2]; pfd[0].fd = wl_display_get_fd(display); pfd[0].events = events; + pfd[1].fd = signal_fd; + pfd[1].events = POLLIN; + do { - ret = poll(pfd, 1, -1); + ret = poll(pfd, 2, -1); + + if (ret > 0 && pfd[1].revents) + signal_int(signal_fd); } while (ret == -1 && errno == EINTR && running); if(0 == running) @@ -779,9 +799,11 @@ display_poll(struct wl_display *display, short int events) * the poll is continuing because the generated errno is EINTR, * so added running flag also to decide whether to continue polling or not */ static int -display_dispatch(struct wl_display *display) +display_dispatch(WaylandContextStruct *wlcontext) { int ret; + int signal_fd = wlcontext->signal_fd; + struct wl_display *display = wlcontext->wl_display; if (wl_display_prepare_read(display) == -1) return wl_display_dispatch_pending(display); @@ -792,7 +814,7 @@ display_dispatch(struct wl_display *display) if (ret != -1 || errno != EAGAIN) break; - if (display_poll(display, POLLOUT) == -1) { + if (display_poll(display, signal_fd, POLLOUT) == -1) { wl_display_cancel_read(display); return -1; } @@ -805,7 +827,7 @@ display_dispatch(struct wl_display *display) return -1; } - if (display_poll(display, POLLIN) == -1) { + if (display_poll(display, signal_fd, POLLIN) == -1) { wl_display_cancel_read(display); return -1; } @@ -821,16 +843,28 @@ int main (int argc, const char * argv[]) WaylandContextStruct* wlcontext; BkGndSettingsStruct* bkgnd_settings; - struct sigaction sigint; int ret = 0; - - sigint.sa_handler = signal_int; - sigemptyset(&sigint.sa_mask); - sigaction(SIGINT, &sigint, NULL); - sigaction(SIGTERM, &sigint, NULL); - sigaction(SIGSEGV, &sigint, NULL); + sigset_t mask; wlcontext = (WaylandContextStruct*)calloc(1, sizeof(WaylandContextStruct)); + wlcontext->signal_fd = -1; + + ret = sigemptyset(&mask); + sigaddset(&mask, SIGINT); + sigaddset(&mask, SIGTERM); + ret = sigprocmask(SIG_BLOCK, &mask, NULL); + if (ret == -1) { + fprintf(stderr, "sigprocmask failed with error '%s'\n", + strerror(errno)); + return -1; + } + + wlcontext->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC); + if (wlcontext->signal_fd < 0) { + fprintf(stderr, "invalid signalfd file descriptor. error '%s'\n", + strerror(errno)); + goto ErrorSignalFd; + } /*get bkgnd settings and create shm-surface*/ bkgnd_settings = get_bkgnd_settings_cursor_info(wlcontext); @@ -883,7 +917,7 @@ int main (int argc, const char * argv[]) draw_bkgnd_surface(wlcontext); while (running && (ret != -1)) - ret = display_dispatch(wlcontext->wl_display); + ret = display_dispatch(wlcontext); Error: #ifdef LIBWESTON_DEBUG_PROTOCOL @@ -924,6 +958,8 @@ ErrorContext: destroy_wayland_context(wlcontext); free(bkgnd_settings); + close(wlcontext->signal_fd); +ErrorSignalFd: free(wlcontext); return 0; -- cgit v1.2.1