<commit_before>// Copyright (c) 2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_SCHEDULER_H
#define BITCOIN_SCHEDULER_H

#include <sync.h>

#include <condition_variable>
#include <functional>
#include <list>
#include <map>

//
// Simple class for background tasks that should be run periodically or once
// "after a while"
//
// Usage:
//
// CScheduler* s = new CScheduler();
// // Assuming a: void doSomething() { }
// s->scheduleFromNow(doSomething, std::chrono::milliseconds{11});
// s->scheduleFromNow([=] { this->func(argument); },
//                    std::chrono::milliseconds{3});
// std::thread *t = new std::thread([?] { s->serviceQueue(); });
//
// ... then at program shutdown, make sure to call stop() to clean up the
// thread(s) running serviceQueue:
// s->stop();
// t->join();
// delete t;
// delete s; // Must be done after thread is interrupted/joined.
//

class CScheduler {
public:
    CScheduler();
    ~CScheduler();

    typedef std::function<void()> Function;
    typedef std::function<bool()> Predicate;

    // Call func at/after time t
    void schedule(Function f, std::chrono::system_clock::time_point t);

    /** Call f once after the delta has passed */
    void scheduleFromNow(Function f, std::chrono::milliseconds delta) {
        schedule(std::move(f), std::chrono::system_clock::now() + delta);
    }

    /**
     * Repeat p until it return false. First run is after delta has passed once.
     *
     * The timing is not exact: Every time p is finished, it is rescheduled to
     * run again after delta. If you need more accurate scheduling, don't use
     * this method.
     */
    void scheduleEvery(Predicate p, std::chrono::milliseconds delta);

    /**
     * Mock the scheduler to fast forward in time.
     * Iterates through items on taskQueue and reschedules them
     * to be delta_seconds sooner.
     */
    void MockForward(std::chrono::seconds delta_seconds);

    // To keep things as simple as possible, there is no unschedule.

    // Services the queue 'forever'. Should be run in a thread, and interrupted
    // using boost::interrupt_thread
    void serviceQueue();

    // Tell any threads running serviceQueue to stop as soon as they're done
    // servicing whatever task they're currently servicing (drain=false) or when
    // there is no work left to be done (drain=true)
    void stop(bool drain = false);

    // Returns number of tasks waiting to be serviced,
    // and first and last task times<commit_msg>doc: Remove unused documentation about unimplemented features<commit_after>// Copyright (c) 2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_SCHEDULER_H
#define BITCOIN_SCHEDULER_H

#include <sync.h>

#include <condition_variable>
#include <functional>
#include <list>
#include <map>

//
// Simple class for background tasks that should be run periodically or once
// "after a while"
//
// Usage:
//
// CScheduler* s = new CScheduler();
// // Assuming a: void doSomething() { }
// s->scheduleFromNow(doSomething, std::chrono::milliseconds{11});
// s->scheduleFromNow([=] { this->func(argument); },
//                    std::chrono::milliseconds{3});
// std::thread *t = new std::thread([?] { s->serviceQueue(); });
//
// ... then at program shutdown, make sure to call stop() to clean up the
// thread(s) running serviceQueue:
// s->stop();
// t->join();
// delete t;
// delete s; // Must be done after thread is interrupted/joined.
//
class CScheduler {
public:
    CScheduler();
    ~CScheduler();

    typedef std::function<void()> Function;
    typedef std::function<bool()> Predicate;

    // Call func at/after time t
    void schedule(Function f, std::chrono::system_clock::time_point t);

    /** Call f once after the delta has passed */
    void scheduleFromNow(Function f, std::chrono::milliseconds delta) {
        schedule(std::move(f), std::chrono::system_clock::now() + delta);
    }

    /**
     * Repeat p until it return false. First run is after delta has passed once.
     *
     * The timing is not exact: Every time p is finished, it is rescheduled to
     * run again after delta. If you need more accurate scheduling, don't use
     * this method.
     */
    void scheduleEvery(Predicate p, std::chrono::milliseconds delta);

    /**
     * Mock the scheduler to fast forward in time.
     * Iterates through items on taskQueue and reschedules them
     * to be delta_seconds sooner.
     */
    void MockForward(std::chrono::seconds delta_seconds);

    // Services the queue 'forever'. Should be run in a thread, and interrupted
    // using boost::interrupt_thread
    void serviceQueue();

    // Tell any threads running serviceQueue to stop as soon as they're done
    // servicing whatever task they're currently servicing (drain=false) or when
    // there is no work left to be done (drain=true)
    void stop(bool drain = false);

    // Returns number of tasks waiting to be serviced,
    // and first and last task times
{'fraction_non_alphanumeric': 0.12315648343229267, 'fraction_numerical': 0.002681478643937943, 'mean_word_length': 3.2112903225806453, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '5955427', 'n_tokens_mistral': 1513, 'n_tokens_neox': 1472, 'n_words': 554}