<commit_before>#ifndef DASYNQ_INTERRUPT_H_INCLUDED
#define DASYNQ_INTERRUPT_H_INCLUDED

#include <unistd.h>
#include <fcntl.h>

#include "dasynq-config.h"
#include "dasynq-mutex.h"

/*
 * Mechanism for interrupting an event loop wait.
 */

namespace dasynq {

template <typename Base, typename Mutex = typename Base::mutex_t> class interrupt_channel;

// In the non-multi-thread case, this doesn't need to be supported:
template <typename Base> class interrupt_channel<Base, NullMutex> : public Base
{
    public:
    void interrupt_wait()
    {

    }
};

template <typename Base, typename Mutex> class interrupt_channel : public Base
{
#ifdef HAVE_PIPE2
    int create_pipe(int filedes[2])
    {
        return pipe2(filedes, O_CLOEXEC | O_NONBLOCK);
    }
#else
    int create_pipe(int filedes[2])
    {
        int r = pipe(filedes);
        if (r != -1) {
            fcntl(filedes[0], F_SETFD, O_CLOEXEC);
            fcntl(filedes[1], F_SETFD, O_CLOEXEC);
            fcntl(filedes[0], F_SETFL, O_NONBLOCK);
            fcntl(filedes[1], F_SETFL, O_NONBLOCK);
        }
        return r;
    }
#endif

    int pipe_r_fd;
    int pipe_w_fd;

    public:

    template <typename T> void init(T *loop_mech)
    {
        int pipedes[2];
        if (create_pipe(pipedes) == -1) {
            throw std::system_error(errno, std::system_category());
        }

        pipe_r_fd = pipedes[0];
        pipe_w_fd = pipedes[1];

        try {
            loop_mech->addFdWatch(pipe_r_fd, &pipe_r_fd, IN_EVENTS);
        }
        catch (...) {
            close (pipe_r_fd);
            close (pipe_w_fd);
            throw;
        }<commit_msg>interrupt_channel: Call Base::init from init.<commit_after>#ifndef DASYNQ_INTERRUPT_H_INCLUDED
#define DASYNQ_INTERRUPT_H_INCLUDED

#include <unistd.h>
#include <fcntl.h>

#include "dasynq-config.h"
#include "dasynq-mutex.h"

/*
 * Mechanism for interrupting an event loop wait.
 */

namespace dasynq {

template <typename Base, typename Mutex = typename Base::mutex_t> class interrupt_channel;

// In the non-multi-thread case, this doesn't need to be supported:
template <typename Base> class interrupt_channel<Base, NullMutex> : public Base
{
    public:
    void interrupt_wait()
    {

    }
};

template <typename Base, typename Mutex> class interrupt_channel : public Base
{
#ifdef HAVE_PIPE2
    int create_pipe(int filedes[2])
    {
        return pipe2(filedes, O_CLOEXEC | O_NONBLOCK);
    }
#else
    int create_pipe(int filedes[2])
    {
        int r = pipe(filedes);
        if (r != -1) {
            fcntl(filedes[0], F_SETFD, O_CLOEXEC);
            fcntl(filedes[1], F_SETFD, O_CLOEXEC);
            fcntl(filedes[0], F_SETFL, O_NONBLOCK);
            fcntl(filedes[1], F_SETFL, O_NONBLOCK);
        }
        return r;
    }
#endif

    int pipe_r_fd;
    int pipe_w_fd;

    public:

    template <typename T> void init(T *loop_mech)
    {
        int pipedes[2];
        if (create_pipe(pipedes) == -1) {
            throw std::system_error(errno, std::system_category());
        }

        pipe_r_fd = pipedes[0];
        pipe_w_fd = pipedes[1];

        try {
            loop_mech->addFdWatch(pipe_r_fd, &pipe_r_fd, IN_EVENTS);
        }
        catch (...) {
            close (pipe_r_fd);
            close (pipe_w_fd);
            throw;
        }

        Base::init(loop_mech);
{'fraction_non_alphanumeric': 0.11366348448687351, 'fraction_numerical': 0.007756563245823389, 'mean_word_length': 2.4854469854469854, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 19, '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': '5172158', 'n_tokens_mistral': 1206, 'n_tokens_neox': 1181, 'n_words': 259}