Skip to content
Snippets Groups Projects
Select Git revision
  • 029ffa88d7e78fb604f9226428d598ae50bbe470
  • master default protected
  • release/202005
  • release/202001
  • release/201912
  • release/windows-test/201910
  • release/201908
  • release/201906
  • release/201905
  • release/201904
  • release/201903
  • release/201902
  • release/201901
  • release/201812
  • release/201811
  • release/201808
  • releases/beta1
  • packaging
  • releases/alpha
  • 1.0.0
  • 0.2.0
  • 0.1.0
22 results

RingMainWindow.mm

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    scheduler.h 3.68 KiB
    /*
     *  Copyright (C) 2014-2016 Savoir-faire Linux Inc.
     *  Author(s) : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
     *              Simon Désaulniers <sim.desaulniers@gmail.com>
     *
     *  This program is free software; you can redistribute it and/or modify
     *  it under the terms of the GNU General Public License as published by
     *  the Free Software Foundation; either version 3 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 General Public License for more details.
     *
     *  You should have received a copy of the GNU 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 "utils.h"
    
    #include <functional>
    #include <map>
    
    namespace dht {
    
    /*!
     * @class   Scheduler
     * @brief   Job scheduler
     * @details
     * Maintains the timings upon which to execute a job.
     */
    class Scheduler {
    public:
        struct Job {
            bool done;
            bool cancelled;
            time_point time;
            std::function<void()> do_;
        };
    
        /**
         * Adds another job to the queue.
         *
         * @param time  The time upon which the job shall be executed.
         * @param job_func  The job function to execute.
         *
         * @return pointer to the newly scheduled job.
         */
        std::shared_ptr<Scheduler::Job> add(time_point time, std::function<void()> job_func) {
            auto scheduled_time = std::max(time, now); /* This should prevent running an auto rescheduling job forever
                                                          before the Scheduler::run method ends. */
            auto job = std::make_shared<Job>(Job {false, false, scheduled_time, std::move(job_func)});
            timers.emplace(std::move(scheduled_time), job);
            return job;
        }
    
        /**
         * Reschedules a job.
         *
         * @param time  The time at which the job shall be rescheduled.
         * @param job  The job to edit.
         *
         * @return pointer to the newly scheduled job.
         */
        std::shared_ptr<Scheduler::Job> edit(const std::shared_ptr<Scheduler::Job>& job, time_point time) {
            if (not job)
                return {};
            job->cancelled = true;
            return add(time, std::move(job->do_));
        }
    
        /**
         * Runs the jobs to do up to now.
         *
         * @return The time for the next job to run.
         */
        time_point run() {
            syncTime();
            while (not timers.empty()) {
                auto timer = timers.begin();
                /*
                 * Running jobs scheduled before "now" prevents run+rescheduling
                 * loops before this method ends. It is garanteed by the fact that a
                 * job will at least be scheduled for "now" and not before.
                 */
                if (not (timer->first < now))
                    break;
    
                auto& job = timer->second;
                if (not job->cancelled and job->do_) {
                    job->do_();
                    job->done = true;
                }
                timers.erase(timer);
            }
            return getNextJobTime();
        }
    
        inline time_point getNextJobTime() const {
            return not timers.empty() ? timers.begin()->first : time_point::max();
        }
    
        /**
         * Accessors for the common time reference used for synchronizing
         * operations.
         */
        inline const time_point& time() const { return now; }
        inline time_point syncTime() { return (now = clock::now()); }
    
    private:
        time_point now {clock::now()};
        std::multimap<time_point, std::shared_ptr<Job>> timers {}; /* the jobs ordered by time */
    };
    
    }