decompose wl_backend.c: extract wl_signalfd.c

This commit is contained in:
Window Maker 2026-06-02 10:45:56 +02:00
parent 33f686c79f
commit ba7b7de898
4 changed files with 112 additions and 86 deletions

View File

@ -167,7 +167,8 @@ wmaker_SOURCES += \
backend/wayland/wl_client.c \
backend/wayland/wl_icccm.c \
backend/wayland/wl_framebuf.c \
backend/wayland/wl_atom.c
backend/wayland/wl_atom.c \
backend/wayland/wl_signalfd.c
endif
if USE_NESTED_FUNC

View File

@ -3111,91 +3111,6 @@ wl_display_default_screen(void)
}
/* ------------------------------------------------------------------ */
/* Phase 29+: signalfd-based signal handling */
/* ------------------------------------------------------------------ */
/*
* wl_signalfd_handler -- called from within wl_event_loop_dispatch() when
* SIGTERM, SIGINT, or SIGHUP is pending on the signalfd.
*
* Running inside the event loop means we can safely call
* wl_display_terminate() without risking a re-entrant call into the Wayland
* event loop machinery, which is the failure mode of the traditional
* signal-handler → DispatchEvent → wl_display_terminate path.
*/
static int
wl_signalfd_handler(int fd, uint32_t mask, void *data)
{
struct signalfd_siginfo info;
ssize_t n;
(void)mask; (void)data;
n = read(fd, &info, sizeof(info));
if (n != (ssize_t)sizeof(info))
return 0;
wwarning("wl_backend: signalfd received signal %u - terminating event loop",
(unsigned)info.ssi_signo);
/* Set the exit state flag so post-loop cleanup paths see it. */
SIG_WCHANGE_STATE(WSTATE_NEED_EXIT);
/* Terminate the event loop. */
wl_state.terminate = 1;
return 0;
}
#ifdef HAVE_INOTIFY
static void wl_handle_inotify_events(void)
{
ssize_t eventQLength;
size_t i = 0;
char buff[(sizeof(struct inotify_event) + NAME_MAX + 1) * 5];
int oneShotFlag = 0;
eventQLength = read(w_global.inotify.fd_event_queue, buff, sizeof(buff));
if (eventQLength < 0) {
wwarning(_("read problem when trying to get INotify event: %s"), strerror(errno));
return;
}
while (i < (size_t)eventQLength) {
struct inotify_event *pevent = (struct inotify_event *)&buff[i];
if (pevent->mask & IN_DELETE_SELF) {
wwarning(_("the defaults database has been deleted!"));
if (w_global.inotify.fd_event_queue >= 0) {
close(w_global.inotify.fd_event_queue);
w_global.inotify.fd_event_queue = -1;
}
}
if (pevent->mask & IN_UNMOUNT) {
wwarning(_("the unit containing the defaults database has been unmounted."));
if (w_global.inotify.fd_event_queue >= 0) {
close(w_global.inotify.fd_event_queue);
w_global.inotify.fd_event_queue = -1;
}
wPreferences.flags.noupdates = 1;
}
/* React on IN_MOVED_TO (atomic rename — WMWritePropListToFile pattern)
* or IN_CLOSE_WRITE for direct writes. Skip temp files (they have
* a dot in their name like 'WindowMaker.XXXXXX'). */
if (oneShotFlag == 0 && pevent->len > 0) {
const char *name = pevent->name;
int is_tempfile = (strchr(name, '.') != NULL);
if (((pevent->mask & IN_MOVED_TO) ||
((pevent->mask & IN_CLOSE_WRITE) && !is_tempfile))) {
wDefaultsCheckDomains(NULL);
oneShotFlag = 1;
}
}
i += sizeof(struct inotify_event) + pevent->len;
}
}
#endif
static void
wl_event_loop_run(void)
{

View File

@ -0,0 +1,106 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/signalfd.h>
#ifdef HAVE_INOTIFY
#include <sys/inotify.h>
#include <limits.h>
#endif
#include <wayland-server-core.h>
#include "../../screen.h"
/* Forward declaration */
void wDefaultsCheckDomains(void *arg);
#include "wl_types.h"
/* ------------------------------------------------------------------ */
/* Phase 29+: signalfd-based signal handling */
/* ------------------------------------------------------------------ */
/*
* wl_signalfd_handler -- called from within wl_event_loop_dispatch() when
* SIGTERM, SIGINT, or SIGHUP is pending on the signalfd.
*
* Running inside the event loop means we can safely call
* wl_display_terminate() without risking a re-entrant call into the Wayland
* event loop machinery, which is the failure mode of the traditional
* signal-handler → DispatchEvent → wl_display_terminate path.
*/
int
wl_signalfd_handler(int fd, uint32_t mask, void *data)
{
struct signalfd_siginfo info;
ssize_t n;
(void)mask; (void)data;
n = read(fd, &info, sizeof(info));
if (n != (ssize_t)sizeof(info))
return 0;
wwarning("wl_backend: signalfd received signal %u - terminating event loop",
(unsigned)info.ssi_signo);
/* Set the exit state flag so post-loop cleanup paths see it. */
SIG_WCHANGE_STATE(WSTATE_NEED_EXIT);
/* Terminate the event loop. */
wl_state.terminate = 1;
return 0;
}
#ifdef HAVE_INOTIFY
void wl_handle_inotify_events(void)
{
ssize_t eventQLength;
size_t i = 0;
char buff[(sizeof(struct inotify_event) + NAME_MAX + 1) * 5];
int oneShotFlag = 0;
eventQLength = read(w_global.inotify.fd_event_queue, buff, sizeof(buff));
if (eventQLength < 0) {
wwarning(_("read problem when trying to get INotify event: %s"), strerror(errno));
return;
}
while (i < (size_t)eventQLength) {
struct inotify_event *pevent = (struct inotify_event *)&buff[i];
if (pevent->mask & IN_DELETE_SELF) {
wwarning(_("the defaults database has been deleted!"));
if (w_global.inotify.fd_event_queue >= 0) {
close(w_global.inotify.fd_event_queue);
w_global.inotify.fd_event_queue = -1;
}
}
if (pevent->mask & IN_UNMOUNT) {
wwarning(_("the unit containing the defaults database has been unmounted."));
if (w_global.inotify.fd_event_queue >= 0) {
close(w_global.inotify.fd_event_queue);
w_global.inotify.fd_event_queue = -1;
}
wPreferences.flags.noupdates = 1;
}
/* React on IN_MOVED_TO (atomic rename — WMWritePropListToFile pattern)
* or IN_CLOSE_WRITE for direct writes. Skip temp files (they have
* a dot in their name like 'WindowMaker.XXXXXX'). */
if (oneShotFlag == 0 && pevent->len > 0) {
const char *name = pevent->name;
int is_tempfile = (strchr(name, '.') != NULL);
if (((pevent->mask & IN_MOVED_TO) ||
((pevent->mask & IN_CLOSE_WRITE) && !is_tempfile))) {
wDefaultsCheckDomains(NULL);
oneShotFlag = 1;
}
}
i += sizeof(struct inotify_event) + pevent->len;
}
}
#endif

View File

@ -499,3 +499,7 @@ void fb_attach_tree_listener(struct wl_frame_buf *fb);
void fb_attach_scene_buf_listener(struct wl_frame_buf *fb);
void wl_frame_paint_button(WCoreWindow *button, WTexture *texture, unsigned long color, WPixmap *image, int pushed);
unsigned long wl_atom_intern(const char *name);
/* Signalfd module declarations (extracted to wl_signalfd.c) */
int wl_signalfd_handler(int fd, uint32_t mask, void *data);
void wl_handle_inotify_events(void);