<commit_before>/*
 * DISTRHO Plugin Framework (DPF)
 * Copyright (C) 2012-2016 <NAME> <<EMAIL>>
 *
 * Permission to use, copy, modify, and/or distribute this software for any purpose with
 * or without fee is hereby granted, provided that the above copyright notice and this
 * permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef DISTRHO_EXTERNAL_WINDOW_HPP_INCLUDED
#define DISTRHO_EXTERNAL_WINDOW_HPP_INCLUDED

#include "../DistrhoUtils.hpp"

START_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------
// ExternalWindow class

class ExternalWindow
{
public:
    ExternalWindow(const uint w = 1, const uint h = 1)
        : width(w),
          height(h) {}

    uint getWidth() const noexcept
    {
        return width;
    }

    uint getHeight() const noexcept
    {
        return height;
    }

    void setSize(const uint w, const uint h) noexcept
    {
        DISTRHO_SAFE_ASSERT_RETURN(w > 0 && h > 0,)

        width = w;
        height = h;
    }

private:
    uint width;
    uint height;

    DISTRHO_DECLARE_NON_COPY_CLASS(ExternalWindow)
};

// -----------------------------------------------------------------------

END_NAMESPACE_DISTRHO

#endif // DISTRHO_EXTERNAL_WINDOW_HPP_INCLUDED
<commit_msg>ExternalWindow: Add code for managing external process<commit_after>/*
 * DISTRHO Plugin Framework (DPF)
 * Copyright (C) 2012-2016 <NAME> <<EMAIL>>
 *
 * Permission to use, copy, modify, and/or distribute this software for any purpose with
 * or without fee is hereby granted, provided that the above copyright notice and this
 * permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef DISTRHO_EXTERNAL_WINDOW_HPP_INCLUDED
#define DISTRHO_EXTERNAL_WINDOW_HPP_INCLUDED

#include "../DistrhoUtils.hpp"

#ifdef DISTRHO_OS_UNIX
# include <cerrno>
# include <sys/wait.h>
# include <unistd.h>
#else
# error Unsupported platform!
#endif

START_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------
// ExternalWindow class

class ExternalWindow
{
public:
    ExternalWindow(const uint w = 1, const uint h = 1)
        : width(w),
          height(h),
          pid(0) {}

    ~ExternalWindow()
    {
        terminateAndWaitForProcess();
    }

    uint getWidth() const noexcept
    {
        return width;
    }

    uint getHeight() const noexcept
    {
        return height;
    }

    bool isRunning() noexcept
    {
        if (pid <= 0)
            return false;

        const pid_t p = ::waitpid(pid, nullptr, WNOHANG);

        if (p == pid || (p == -1 && errno == ECHILD))
        {
            printf("NOTICE: Child process exited while idle\n");
            pid = 0;
            return false;
        }

        return true;
    }

protected:
    bool startExternalProcess(const char* args[])
    {
        terminateAndWaitForProcess();

        pid = vfork();

        switch (pid)
        {
        case 0:
            execvp(args[0], (char**)args);
            _exit(1);
            return false;

        case -1:
            printf("Could not start external ui\n");
            return false;

        default:
            return true;
        }
    }

private:
    uint width;
    uint height;
    pid_t pid;

    friend class UIExporter;

    void terminateAndWaitForProcess()
    {
        if (pid <= 0)
            return;

        printf("Waiting for previous process to stop,,,\n");

        bool sendTerm = true;

        for (pid_t p;;)
        {
            p = ::waitpid(pid, nullptr, WNOHANG);

            switch (p)
            {
            case 0:
                if (sendTerm)
                {
                    sendTerm = false;
                    ::kill(pid, SIGTERM);
                }
                break;

            case -1:
                if (errno == ECHILD)
                {
                    printf("Done! (no such process)\n");
                    pid = 0;
                    return;
                }
                break;

            default:
                if (p == pid)
                {
                    printf("Done! (clean wait)\n");
                    pid = 0;
                    return;
                }
                break;
            }

            // 5 msec
            usleep(5*1000);
        }
    }

    DISTRHO_DECLARE_NON_COPY_CLASS(ExternalWindow)
};

// -----------------------------------------------------------------------

END_NAMESPACE_DISTRHO

#endif // DISTRHO_EXTERNAL_WINDOW_HPP_INCLUDED

{'fraction_non_alphanumeric': 0.13049024968106435, 'fraction_numerical': 0.00747220703480955, 'mean_word_length': 1.7114624505928853, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 14, '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': '2208720', 'n_tokens_mistral': 1599, 'n_tokens_neox': 1462, 'n_words': 493}