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
|
#include <QJsonArray>
#include <QJsonObject>
#include <QtDebug>
#include <QString>
#include <unistd.h>
#include <iostream>
#include <QtCore>
#include <message.h>
#include "taskmanager.h"
TaskManager::TaskManager(QObject* parent) : QObject(parent), m_loop(nullptr) {
}
TaskManager::~TaskManager() {
delete m_loop;
}
void TaskManager::open(const QUrl &bindingAddress)
{
m_loop = new MessageEngine(bindingAddress);
QObject::connect(m_loop, &MessageEngine::connected, this, &TaskManager::onConnected);
QObject::connect(m_loop, &MessageEngine::messageReceived, this, &TaskManager::onMessageReceived);
}
void TaskManager::onConnected()
{
query(); // let's not wait 3 seconds and issue the first call directly
timer = new QTimer();
connect(timer, SIGNAL(timeout()), this, SLOT(query()));
timer->start(3000);
}
void TaskManager::kill(int tid) {
callService("kill_process", QJsonValue(tid));
}
void TaskManager::query() {
callService("get_process_list",
QJsonValue(QJsonObject({{"processes", QJsonValue()}})));
}
void TaskManager::callService(const QString& command, QJsonValue value) {
Message *msg = new Message();
msg->createRequest("taskmanager", command, value);
qDebug() << "sending message " << msg->toJson();
m_loop->sendMessage(msg);
delete msg;
}
void TaskManager::onMessageReceived(MessageType type, Message *message)
{
if (type == ResponseRequestMessage)
ProcessResponse(message);
}
void TaskManager::ProcessResponse(Message *message)
{
qDebug() << "got message " << message->toJson();
QString msgType = message->replyData()["msgType"].toString();
if (msgType.isNull())
return; // no type supplied, ignoring
if (QString::compare(msgType, "processList") == 0) {
QJsonArray processes = message->replyData()["processes"].toArray();
ProcessResponseTasklist(processes);
}
// more response types to follow
}
void TaskManager::ProcessResponseTasklist(QJsonArray& processes)
{
std::vector<ProcInfo> procs;
if (processes.size() == 0) {
// this is not a valid process list response
return;
}
for(auto it = processes.constBegin(); it != processes.constEnd(); ++it) {
ProcInfo Proc(it->toObject());
procs.push_back(Proc);
}
int flag;
if(m_procinfos.empty()){
for(auto it = procs.begin(); it != procs.end(); ++it){ // if m_procinfos is empty then this is first call
emit addProcess(it->cmd(), it->tid(), it->euid(), it->scpu(), it->ucpu(), it->resident_memory(), it->state());
}
} else {
for(auto it = procs.begin(); it != procs.end(); ++it){ // loop through procs, it = procs element (ProcInfo obj)
flag = 0;
for(auto it2 = m_procinfos.begin(); it2 != m_procinfos.end(); ++it2){ // loop through m_procinfos, it2 m_procinfos element (ProcInfo obj)
// if(*it == *it2){ // if the same ID exists in both vectors
if(it->tid() == it2->tid()){
if(it->cmd() == it2->cmd()){ // if the name is still the same
if(!(it == it2)){ // if the same process has new data
emit updateProcess(it->cmd(), it->tid(), it->euid(), it->scpu(), it->ucpu(), it->resident_memory(), it->state());
m_procinfos.erase(it2);
flag = 1;
break;
}
} else { // process in m_procinfos has died and a new one has its ID
qDebug() << "The process ID has been reused for another process";
emit updateProcess(it->cmd(), it->tid(), it->euid(), it->scpu(), it->ucpu(), it->resident_memory(), it->state());
m_procinfos.erase(it2);
flag = 1;
}
}
}
if(flag == 0){ // if no ID was found in old vector; that means it's a new process
qDebug() << it->cmd() << " process has been added";
emit addProcess(it->cmd(), it->tid(), it->euid(), it->scpu(), it->ucpu(), it->resident_memory(), it->state());
}
}
for(auto it2 = m_procinfos.begin(); it2 != m_procinfos.end(); ++it2){ // remaining processes in m_procinfos are all dead
qDebug() << "Dead processes are removed";
qDebug() << it2->cmd();
emit removeProcess(it2->tid());
}
}
m_procinfos = procs;
}
|