<commit_before>/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2016-2019 <NAME>, Videolabs, VideoLAN
 *
 * Authors: <NAME> <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#pragma once

#include "compat/Mutex.h"

#if CXX11_THREADS

#include <condition_variable>

namespace medialibrary
{
namespace compat
{
    using ConditionVariable = std::condition_variable;
}
}

#else
#ifdef _WIN32
#include <windows.h>

namespace medialibrary
{
namespace compat
{
class ConditionVariable
{
public:
    using native_handle_type = PCONDITION_VARIABLE;
    ConditionVariable()
    {
        InitializeConditionVariable( &m_cond );
    }

    void notify_one() noexcept
    {
        WakeConditionVariable( &m_cond );
    }

    void notify_all() noexcept
    {
        WakeAllConditionVariable( &m_cond );
    }

    void wait( std::unique_lock<Mutex>& lock )
    {
        SleepConditionVariableCS( &m_cond, lock.mutex()->native_handle(), INFINITE );
    }

    template <typename Pred>
    void wait( std::unique_lock<Mutex>& lock, Pred pred )
    {
        while ( pred() == false )
            wait( lock );
    }

    template <typename Rep, typename Period, typename Pred>
    bool wait_for( std::unique_lock<Mutex>& lock, const std::chrono::duration<Rep, Period>& relTime, Pred pred )
    {
        auto timeout = std::chrono::duration_cast<std::chrono::milliseconds>( relTime );
        while ( pred() == false )
        {
            auto now = std::chrono::system_clock::now();
            if ( SleepConditionVariableCS( &m_cond, lock.mutex()->native_handle(), timeout.count() ) == 0 )
            {
                auto res = GetLastError();
                if ( res == ERROR_TIMEOUT )
                    return false;
                throw std::system_error{ std::make_error_code( std::errc::resource_unavailable_try_again ) };
            }
            timeout -= std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::system_clock::now() - now );
        }
        return true;
    }

    template <typename Clock, typename Period, typename Pred>
    bool wait_until( std::unique_lock<Mutex>& lock, const std::chrono::time_point<Clock, Period>& relTime, Pred&& pred )
    {
        auto timeout = relTime - std::chrono::steady_clock::now();
        return wait_for( lock, timeout, std::forward<Pred>( pred ) );
    }

    native_handle_type native_handle()
    {
        return &m_cond;
    }

private:
    CONDITION_VARIABLE m_cond;
};
}
}
<commit_msg>compat: ConditionVariable: Use steady_clock instead of system_clock<commit_after>/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2016-2019 <NAME>, Videolabs, VideoLAN
 *
 * Authors: <NAME> <<EMAIL>>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#pragma once

#include "compat/Mutex.h"

#if CXX11_THREADS

#include <condition_variable>

namespace medialibrary
{
namespace compat
{
    using ConditionVariable = std::condition_variable;
}
}

#else
#ifdef _WIN32
#include <windows.h>

namespace medialibrary
{
namespace compat
{
class ConditionVariable
{
public:
    using native_handle_type = PCONDITION_VARIABLE;
    ConditionVariable()
    {
        InitializeConditionVariable( &m_cond );
    }

    void notify_one() noexcept
    {
        WakeConditionVariable( &m_cond );
    }

    void notify_all() noexcept
    {
        WakeAllConditionVariable( &m_cond );
    }

    void wait( std::unique_lock<Mutex>& lock )
    {
        SleepConditionVariableCS( &m_cond, lock.mutex()->native_handle(), INFINITE );
    }

    template <typename Pred>
    void wait( std::unique_lock<Mutex>& lock, Pred pred )
    {
        while ( pred() == false )
            wait( lock );
    }

    template <typename Rep, typename Period, typename Pred>
    bool wait_for( std::unique_lock<Mutex>& lock, const std::chrono::duration<Rep, Period>& relTime, Pred pred )
    {
        auto timeout = std::chrono::duration_cast<std::chrono::milliseconds>( relTime );
        while ( pred() == false )
        {
            auto now = std::chrono::steady_clock::now();
            if ( SleepConditionVariableCS( &m_cond, lock.mutex()->native_handle(), timeout.count() ) == 0 )
            {
                auto res = GetLastError();
                if ( res == ERROR_TIMEOUT )
                    return false;
                throw std::system_error{ std::make_error_code( std::errc::resource_unavailable_try_again ) };
            }
            timeout -= std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::steady_clock::now() - now );
        }
        return true;
    }

    template <typename Clock, typename Period, typename Pred>
    bool wait_until( std::unique_lock<Mutex>& lock, const std::chrono::time_point<Clock, Period>& relTime, Pred&& pred )
    {
        auto timeout = relTime - std::chrono::steady_clock::now();
        return wait_for( lock, timeout, std::forward<Pred>( pred ) );
    }

    native_handle_type native_handle()
    {
        return &m_cond;
    }

private:
    CONDITION_VARIABLE m_cond;
};
}
}

{'fraction_non_alphanumeric': 0.16656925774400935, 'fraction_numerical': 0.007597895967270602, 'mean_word_length': 3.3350221659278025, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 43, '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': '3688790', 'n_tokens_mistral': 1908, 'n_tokens_neox': 1825, 'n_words': 562}