You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
2.9 KiB
148 lines
2.9 KiB
/* |
|
* Xournal++ |
|
* |
|
* A scheduler for background jobs |
|
* |
|
* Some code from Evince project |
|
* |
|
* @author Xournal++ Team |
|
* https://github.com/xournalpp/xournalpp |
|
* |
|
* @license GNU GPLv2 or later |
|
*/ |
|
|
|
#pragma once |
|
|
|
#include <array> |
|
#include <condition_variable> |
|
#include <deque> |
|
#include <mutex> |
|
#include <string> |
|
|
|
#include <gtk/gtk.h> |
|
|
|
#include "Job.h" |
|
|
|
/** |
|
* @file Scheduler.h |
|
* @brief A file containing the definition of the Scheduler |
|
*/ |
|
|
|
/** |
|
* @enum JobPriority |
|
* |
|
* The priority of the job affects the order of execution: |
|
* Jobs with higher priority are processed before the |
|
* lower ones. |
|
*/ |
|
enum JobPriority { |
|
/** |
|
* Urgent: used for rendering the current page |
|
*/ |
|
JOB_PRIORITY_URGENT, |
|
|
|
/** |
|
* High: used for rendering thumbnail ranges |
|
*/ |
|
JOB_PRIORITY_HIGH, |
|
|
|
/** |
|
* Low: used for rendering of pages not in the current range |
|
*/ |
|
JOB_PRIORITY_LOW, |
|
|
|
/** |
|
* None: used for any other job (loading / saving / printing...) |
|
*/ |
|
JOB_PRIORITY_NONE, |
|
|
|
/** |
|
* The number of priorities |
|
*/ |
|
JOB_N_PRIORITIES |
|
}; |
|
|
|
|
|
class Scheduler { |
|
public: |
|
Scheduler(); |
|
virtual ~Scheduler(); |
|
|
|
public: |
|
/** |
|
* Adds a Job to the Scheduler |
|
* |
|
* @param Job the job |
|
* @param priority the desired priority |
|
* |
|
* The Job is now owned by the scheduler, and automatically freed if it is done |
|
*/ |
|
void addJob(Job* job, JobPriority priority); |
|
|
|
void start(); |
|
void stop(); |
|
|
|
/** |
|
* Locks the complete scheduler |
|
*/ |
|
void lock(); |
|
|
|
/** |
|
* Unlocks the complete scheduler |
|
*/ |
|
void unlock(); |
|
|
|
/** |
|
* Don't render the next X ms so the scrolling performance is better |
|
*/ |
|
void blockRerenderZoom(); |
|
|
|
/** |
|
* Remove the blocked rendering manually |
|
*/ |
|
void unblockRerenderZoom(); |
|
|
|
private: |
|
static gpointer jobThreadCallback(Scheduler* scheduler); |
|
Job* getNextJobUnlocked(bool onlyNotRender = false, bool* hasRenderJobs = nullptr); |
|
|
|
static bool jobRenderThreadTimer(Scheduler* scheduler); |
|
|
|
protected: |
|
bool threadRunning = true; |
|
|
|
int jobRenderThreadTimerId = 0; |
|
|
|
GThread* thread = nullptr; |
|
|
|
std::condition_variable jobQueueCond{}; |
|
std::mutex jobQueueMutex{}; |
|
std::mutex schedulerMutex{}; |
|
|
|
/** |
|
* This is need to be sure there is no job running if we delete a page. |
|
* If a job is, we may access deleted memory. |
|
*/ |
|
std::mutex jobRunningMutex{}; |
|
|
|
/** |
|
* Jobs of each priority. New jobs |
|
* are added to the back of each queue. |
|
*/ |
|
std::deque<Job*> queueUrgent{}; |
|
std::deque<Job*> queueHigh{}; |
|
std::deque<Job*> queueLow{}; |
|
std::deque<Job*> queueNone{}; |
|
|
|
/** |
|
* Map (JobPriority) -> queue of that priority. |
|
* For example, |
|
* jobQueue[JOB_PRIORITY_URGENT] is &queueUrgent. |
|
*/ |
|
std::array<std::deque<Job*>*, JOB_N_PRIORITIES> jobQueue{}; |
|
|
|
GTimeVal* blockRenderZoomTime = nullptr; |
|
std::mutex blockRenderMutex{}; |
|
|
|
std::string name; |
|
};
|
|
|