1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
#ifndef JOBQUEUE_H
#define JOBQUEUE_H 1
#include <string>
#include <map>
#include <list>
#include <wx/frame.h>
#include <wx/thread.h>
#include <wx/menu.h>
#include <wx/app.h>
#include "UpdateFactory.hpp"
struct JobArgs
{
JobArgs()
: jobid(-1), hostname(""), port(0),
update_file(""), password("") {}
JobArgs(int jobid, UpdateFactory& uf)
: jobid(jobid), hostname(uf.getHostname()),
port(uf.getPort()), update_file(uf.getUpdateFile()),
password(uf.getPassword()) {}
JobArgs(int jobid, const char *hostname, int port,
const char *update_file, const char *password)
: jobid(jobid), hostname(hostname), port(port),
update_file(update_file), password(password) {}
JobArgs(int jobid, std::string& hostname, int port,
std::string& update_file, std::string& password)
: jobid(jobid), hostname(hostname), port(port),
update_file(update_file), password(password) {}
/** randomized (not unique) Job ID */
int jobid;
/* minimum required data for our UpdateFactory */
std::string hostname;
int port;
std::string update_file;
std::string password;
};
struct JobReport : public wxClientData
{
JobReport(double jTime)
: jobTime(jTime) {}
double jobTime;
};
struct Job
{
enum JobEvents
{
/* thread should exit or wants to exit */
eID_THREAD_EXIT = wxID_HIGHEST + 1000,
/* dummy command */
eID_THREAD_NULL,
/* worker thread has started OK */
eID_THREAD_STARTED,
/* process normal job */
eID_THREAD_JOB,
/* job completed */
eID_THREAD_JOB_DONE,
/* process different messages in the frontend */
eID_THREAD_MSG,
eID_THREAD_MSGOK,
eID_THREAD_MSGERR
};
Job() : cmdEvent(eID_THREAD_NULL) {}
Job(JobEvents cmd, JobArgs args) : cmdEvent(cmd), cmdArgs(args) {}
Job(JobEvents cmd, int jobid, UpdateFactory& uf) : cmdEvent(cmd), cmdArgs(jobid, uf) {}
JobEvents cmdEvent;
JobArgs cmdArgs;
};
class Queue
{
public:
enum JobPriority { eHIGHEST, eHIGHER, eNORMAL, eBELOW_NORMAL, eLOW, eIDLE };
Queue(wxEvtHandler *pParent) : m_pParent(pParent), m_busyWorker(0), m_totalJobsDone(0) {}
/* push a job with given priority class onto the FIFO */
void AddJob(const Job& job, const JobPriority& priority = eNORMAL);
Job Pop();
/* report back to parent */
void Report(const Job::JobEvents& cmd, const wxString& sArg = wxEmptyString, int iArg = 0);
void ReportDone(const JobReport& jobReport, const wxString& sArg = wxEmptyString, int iArg = 0);
size_t Stacksize()
{
wxMutexLocker lock(m_MutexQueue);
return m_Jobs.size();
}
size_t getBusyWorker() {
wxMutexLocker lock(m_MutexBusyWorker);
return m_busyWorker;
}
size_t getTotalJobsDone() {
wxMutexLocker lock(m_MutexBusyWorker);
return m_totalJobsDone;
}
void resetTotalJobsDone() {
wxMutexLocker lock(m_MutexBusyWorker);
m_totalJobsDone = 0;
}
void incBusyWorker() {
wxMutexLocker lock(m_MutexBusyWorker);
m_busyWorker++;
}
void decBusyWorker() {
wxMutexLocker lock(m_MutexBusyWorker);
if (m_busyWorker > 0) m_busyWorker--;
m_totalJobsDone++;
}
private:
/** main GUI EventHandler */
wxEvtHandler *m_pParent;
/** a priority Queue using std::multimap */
std::multimap<JobPriority, Job> m_Jobs;
wxMutex m_MutexQueue, m_MutexBusyWorker;
wxSemaphore m_QueueCount;
size_t m_busyWorker, m_totalJobsDone;
};
class WorkerThread : public wxThread
{
public:
WorkerThread(Queue *pQueue, int id = 0) : m_pQueue(pQueue), m_ID(id) { assert(pQueue); wxThread::Create(); }
private:
Queue *m_pQueue;
int m_ID;
wxThread::ExitCode doWork();
virtual wxThread::ExitCode Entry() { return this->doWork(); }
void doJob();
virtual void OnJob() { return this->doJob(); }
};
#endif
|