bool MemoryPressureHandler::tryEnsureEventFD()
{
    // If the env var to use the poll method based on meminfo is set, this method overrides anything else.
    if (m_eventFD != -1 && defaultPollMaximumProcessMemory(s_pollMaximumProcessMemoryCriticalLimit, s_pollMaximumProcessMemoryNonCriticalLimit)) {
        m_eventFD = -1;
        return true;
    }

    if (m_eventFD)
        return true;

    auto setupCgroups = [this]() -> bool {
        int fd = eventfd(0, EFD_CLOEXEC);
        if (fd == -1) {
            LOG(MemoryPressure, "eventfd() failed: %m");
            return false;
        }
        m_eventFD = fd;

        fd = open(s_cgroupMemoryPressureLevel, O_CLOEXEC | O_RDONLY);
        if (fd == -1) {
            logErrorAndCloseFDs("Failed to open memory.pressure_level");
            return false;
        }
        m_pressureLevelFD = fd;

        fd = open(s_cgroupEventControl, O_CLOEXEC | O_WRONLY);
        if (fd == -1) {
            logErrorAndCloseFDs("Failed to open cgroup.event_control");
            return false;
        }

        char line[128] = {0, };
        if (snprintf(line, sizeof(line), "%d %d low", m_eventFD.value(), m_pressureLevelFD.value()) < 0
            || write(fd, line, strlen(line) + 1) < 0) {
            logErrorAndCloseFDs("Failed to write cgroup.event_control");
            close(fd);
            return false;
        }

        return true;
    };

    if (setupCgroups())
        return true;

    return false;
}
void MemoryPressureHandler::install()
{
    if (m_installed)
        return;

    m_eventFD = eventfd(0, EFD_CLOEXEC);
    if (m_eventFD == -1) {
        LOG(MemoryPressure, "eventfd() failed: %m");
        return;
    }

    m_pressureLevelFD = open(s_cgroupMemoryPressureLevel, O_CLOEXEC | O_RDONLY);
    if (m_pressureLevelFD == -1) {
        logErrorAndCloseFDs("Failed to open memory.pressure_level");
        return;
    }

    int fd = open(s_cgroupEventControl, O_CLOEXEC | O_WRONLY);
    if (fd == -1) {
        logErrorAndCloseFDs("Failed to open cgroup.event_control");
        return;
    }

    char line[128] = {0, };
    if (snprintf(line, sizeof(line), "%d %d low", m_eventFD, m_pressureLevelFD) < 0
        || write(fd, line, strlen(line) + 1) < 0) {
        logErrorAndCloseFDs("Failed to write cgroup.event_control");
        close(fd);
        return;
    }
    close(fd);

    m_threadID = createThread(waitForMemoryPressureEvent, this, "WebCore: MemoryPressureHandler");
    if (!m_threadID) {
        logErrorAndCloseFDs("Failed to create a thread for MemoryPressureHandler");
        return;
    }

    if (ReliefLogger::loggingEnabled() && isUnderMemoryPressure())
        LOG(MemoryPressure, "System is no longer under memory pressure.");

    setUnderMemoryPressure(false);
    m_installed = true;
}
void MemoryPressureHandler::uninstall()
{
    if (!m_installed)
        return;

    if (m_threadID) {
        detachThread(m_threadID);
        m_threadID = 0;
    }

    logErrorAndCloseFDs(nullptr);
    m_installed = false;
}