#include #include #include #include #include #include #include #include #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::getExtraInfo(int tid) { callService("get_extra_info", 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); } if (QString::compare(msgType, "extraInfo") == 0) { QJsonObject info = message->replyData()["info"].toObject(); ProcessResponseExtraInfo(info); } // more response types to follow } void TaskManager::ProcessResponseTasklist(QJsonArray& processes) { std::vector 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; } void TaskManager::ProcessResponseExtraInfo(QJsonObject &info) { QString infoString; if (info.size() == 0) { // this is not a valid process list response QTextStream(&infoString) << "procces is not available"; } else { infoString = "Task : " + info["cmd"].toString() + "\n" + "Exec start : " + info["exec_start"].toString() + "\n" + "Exec runtime : " + info["vruntime"].toString() + "\n" + "Prio : " + info["prio"].toString(); } emit showProcessInfo(infoString); }