<commit_before>// Instances of XServerPinger send some simple X requests periodically
// and warn no reply arrives until the next ping.
#include "xserverpinger.h"

#include <QCoreApplication>
#include <QSocketNotifier>
#include <QtDebug>

#include <X11/Xlib.h>
#include <X11/Xlib-xcb.h>

#include <xcb/xcb.h>
#include <xcb/xcbext.h>

#include <signal.h>
#include <sys/prctl.h>

// Ping X in @pingInterval miliseconds.
XServerPinger::XServerPinger(int pingInterval)
{
    Display *dpy;

    // Open a separate connection to X.
    dpy = XOpenDisplay(NULL);
    xcb = XGetXCBConnection(dpy);
    connect(new QSocketNotifier(ConnectionNumber(dpy), QSocketNotifier::Read),
            SIGNAL(activated(int)), SLOT(xInput(int)));

    // XGetInputFocus() is our ping request.
    request = xcb_get_input_focus(xcb);
    xcb_flush(xcb);

    timer = new QTimer();
    connect(timer, SIGNAL(timeout()), SLOT(tick()));
    timer->start(pingInterval);
}

void XServerPinger::xInput(int)
{
    void *reply;
    xcb_generic_error_t *error;
    xcb_generic_event_t *event;

    // X has sent us something, read it.
    if ((event = xcb_poll_for_event(xcb)) != NULL)
        // Some event, ignore it
        free(event);

    if (request.sequence
        && xcb_poll_for_reply(xcb, request.sequence, &reply, &error)) {
        if (reply) {
            free(reply);
            request.sequence = 0;
        } else if (error)
            // Ignore
            free(error);
    }
}

void XServerPinger::tick()
{
    if (!request.sequence) {
        // Last ping was successful, keep pinging.
        request = xcb_get_input_focus(xcb);
        xcb_flush(xcb);
    } else
        // Ping timed out
        qWarning("X is on holidays");
}

// Start a new process and let our parent (the real mcompositor) go.
// Die with the parent.
static void altmain() __attribute__((constructor));
static void altmain()
{
    if (fork())
        return;
    prctl(PR_SET_PDEATHSIG, SIGKILL);

    int meh = 0;
    QCoreApplication app(meh, 0);

    XServerPinger pinger(2500);
    app.exec();
    exit(0);
}<commit_msg>don't launch a new XServerPinger upon restart<commit_after>// Instances of XServerPinger send some simple X requests periodically
// and warn no reply arrives until the next ping.
#include "xserverpinger.h"

#include <QCoreApplication>
#include <QSocketNotifier>
#include <QtDebug>

#include <X11/Xlib.h>
#include <X11/Xlib-xcb.h>

#include <xcb/xcb.h>
#include <xcb/xcbext.h>

#include <signal.h>
#include <sys/prctl.h>

// Ping X in @pingInterval miliseconds.
XServerPinger::XServerPinger(int pingInterval)
{
    Display *dpy;

    // Open a separate connection to X.
    dpy = XOpenDisplay(NULL);
    xcb = XGetXCBConnection(dpy);
    connect(new QSocketNotifier(ConnectionNumber(dpy), QSocketNotifier::Read),
            SIGNAL(activated(int)), SLOT(xInput(int)));

    // XGetInputFocus() is our ping request.
    request = xcb_get_input_focus(xcb);
    xcb_flush(xcb);

    timer = new QTimer();
    connect(timer, SIGNAL(timeout()), SLOT(tick()));
    timer->start(pingInterval);
}

void XServerPinger::xInput(int)
{
    void *reply;
    xcb_generic_error_t *error;
    xcb_generic_event_t *event;

    // X has sent us something, read it.
    if ((event = xcb_poll_for_event(xcb)) != NULL)
        // Some event, ignore it
        free(event);

    if (request.sequence
        && xcb_poll_for_reply(xcb, request.sequence, &reply, &error)) {
        if (reply) {
            free(reply);
            request.sequence = 0;
        } else if (error)
            // Ignore
            free(error);
    }
}

void XServerPinger::tick()
{
    if (!request.sequence) {
        // Last ping was successful, keep pinging.
        request = xcb_get_input_focus(xcb);
        xcb_flush(xcb);
    } else
        // Ping timed out
        qWarning("X is on holidays");
}

// Start XServerPinger in a separate process if it's not running yet.
static void altmain() __attribute__((constructor));
static void altmain()
{
    // Don't run again if the parent restarted.
    if (getenv("XSERVERPINGER"))
        return;
    putenv("XSERVERPINGER=1");

    // Start a new process and let our parent (the real mcompositor) go.
    if (fork())
        return;

    // Die with the parent.
    prctl(PR_SET_PDEATHSIG, SIGKILL);

    int meh = 0;
    QCoreApplication app(meh, 0);

    XServerPinger pinger(2500);
    app.exec();
    exit(0);
}
{'fraction_non_alphanumeric': 0.12494341330918968, 'fraction_numerical': 0.005658669081032141, 'mean_word_length': 2.9002647837599294, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '493762', 'n_tokens_mistral': 1539, 'n_tokens_neox': 1482, 'n_words': 382}