git-svn-id: svn://db.shs.com.ru/pip@803 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2019-06-22 14:55:23 +00:00
parent 71128017dd
commit fb44b01c0f
24 changed files with 433 additions and 142 deletions

View File

@@ -27,6 +27,7 @@ class PIMutex;
class PIThread;
class PITimer;
class PIPeer;
class PIIntrospection;
#define __PIINTROSPECTION_SINGLETON__(T) \
static PIIntrospection##T##Interface * instance() {static PIIntrospection##T##Interface ret; return &ret;} \

View File

@@ -56,6 +56,8 @@ class PIIntrospectionContainers;
#endif
class PIP_EXPORT PIIntrospectionContainersInterface {
friend class PIIntrospection;
friend class PIIntrospectionServer;
public:
__PIINTROSPECTION_SINGLETON__(Containers)

View File

@@ -18,6 +18,7 @@
*/
#include "piintrospection_containers_p.h"
#include <stdio.h>
PIIntrospectionContainers::Type::Type() {
@@ -29,14 +30,17 @@ PIIntrospectionContainers::Type::Type() {
PIIntrospectionContainers::PIIntrospectionContainers() {
crc = standardCRC_32();
}
void PIIntrospectionContainers::containerNew(const char * tn) {
PIMutexLocker _ml(mutex);
uint id = typeID(tn);
typenames[id] = PIStringAscii(tn);
PIMutexLocker _ml(mutex);
//printf("containerNew lock\n");
typenames[id] = tn;
data[id].count++;
//printf("containerNew unlock\n");
}
@@ -74,18 +78,26 @@ uint PIIntrospectionContainers::typeID(const char * tn) {
if (!tn) return 0u;
size_t l = strlen(tn);
if (l == 0) return 0u;
return crc.calculate(tn, l);
return crc.calculate(tn, int(l));
}
PIByteArray & operator <<(PIByteArray & s, const std::unordered_map<uint, std::string> & v) {
PIMap<uint, PIString> m;
for (typename std::unordered_map<uint, std::string>::const_iterator i = v.cbegin(); i != v.cend(); ++i) {
m[i->first] = PIStringAscii(i->second.c_str());
}
s << m;
return s;
}
PIByteArray & operator <<(PIByteArray & s, const PIIntrospectionContainers::Type & v) {
s << v.count << v.items << v.bytes_allocated << v.bytes_used;
return s;
}
PIByteArray & operator >>(PIByteArray & s, PIIntrospectionContainers::Type & v) {
s >> v.count >> v.items >> v.bytes_allocated >> v.bytes_used;
return s;

View File

@@ -20,10 +20,9 @@
#ifndef PIINTROSPECTION_CONTAINERS_P_H
#define PIINTROSPECTION_CONTAINERS_P_H
#define PIP_FORCE_NO_PIINTROSPECTION
#include "pimutex.h"
#include "pimap.h"
#include <unordered_map>
#include <string>
#include "picrc.h"
@@ -48,15 +47,15 @@ public:
ullong bytes_used;
};
PIMap<uint, Type> data;
PIMap<uint, PIString> typenames;
std::unordered_map<uint, Type> data;
std::unordered_map<uint, std::string> typenames;
PIMutex mutex;
CRC_32 crc;
};
PIByteArray & operator <<(PIByteArray & s, const std::unordered_map<uint, std::string> & v);
PIByteArray & operator <<(PIByteArray & s, const PIIntrospectionContainers::Type & v);
PIByteArray & operator >>(PIByteArray & s, PIIntrospectionContainers::Type & v);
#undef PIP_FORCE_NO_PIINTROSPECTION
#endif // PIINTROSPECTION_CONTAINERS_P_H

View File

@@ -18,11 +18,33 @@
*/
#include "piintrospection_server.h"
#include "piintrospection_server_p.h"
#include "pichunkstream.h"
PRIVATE_DEFINITION_START(PIIntrospectionServer)
PIIntrospection::ProcessInfo process_info;
PRIVATE_DEFINITION_END(PIIntrospectionServer)
PIIntrospectionServer::PIIntrospectionServer(): PIPeer(genName()) {
CONNECTU(&itimer, tickEvent, this, timerEvent)
itimer.start(100);
PRIVATE->process_info = PIIntrospection::getInfo();
CONNECTU(&itimer, tickEvent, this, timerEvent);
}
PIIntrospectionServer::~PIIntrospectionServer() {
itimer.stop(false);
if (!itimer.waitForFinish(1000)) {
PIINTROSPECTION_CONTAINERS->p->mutex.unlock();
}
PIPeer::stop();
}
void PIIntrospectionServer::start() {
itimer.start(1000);
PIPeer::start();
}
@@ -33,10 +55,13 @@ PIString PIIntrospectionServer::genName() {
void PIIntrospectionServer::timerEvent() {
PIChunkStream cs;
cs.add(1, PIIntrospection::packInfo())
.add(2, PIIntrospection::packContainers())
.add(3, PIIntrospection::packThreads())
.add(4, PIIntrospection::packObjects());
PIByteArray ba;
/* PIINTROSPECTION_THREADS->mutex.lock();
ba << appname << *(PIINTROSPECTION_CONTAINERS) << PIINTROSPECTION_THREADS->threads.values();
PIINTROSPECTION_THREADS->mutex.unlock();*/
//piCout << "send" << appname;
ba << PIIntrospection::sign;
ba.append(cs.data());
send("__introspection_client__", ba);
}

View File

@@ -21,21 +21,35 @@
#define PIINTROSPECTION_SERVER_H
#include "pipeer.h"
#include "pimutex.h"
class __PIIntrospectionServer__;
class PIIntrospectionServer;
#define PIINTROSPECTION_SERVER (PIIntrospectionServer::instance())
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
# define PIINTROSPECTION_START PIINTROSPECTION_SERVER->start();
#else
# define PIINTROSPECTION_START
#endif
class PIP_EXPORT PIIntrospectionServer: public PIPeer {
PIOBJECT_SUBCLASS(PIIntrospectionServer, PIPeer)
friend class __PIIntrospectionServer__;
PIIntrospectionServer();
public:
PIString appname;
static PIIntrospectionServer * instance() {static PIIntrospectionServer ret; return &ret;}
void start();
private:
PIIntrospectionServer();
~PIIntrospectionServer();
NO_COPY_CLASS(PIIntrospectionServer)
EVENT_HANDLER(void, timerEvent);
PIString genName();
PRIVATE_DECLARATION
PITimer itimer;
};
#endif // PIINTROSPECTION_SERVER_H

View File

@@ -0,0 +1,208 @@
/*
PIP - Platform Independent Primitives
Introspection module - Base server structs
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
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, see <http://www.gnu.org/licenses/>.
*/
#include "piintrospection_server_p.h"
#include "pichunkstream.h"
#include "piinit.h"
#include "pisysteminfo.h"
#include "piobject.h"
const uint PIIntrospection::sign = 0x0F1C2B3A;
PIIntrospection::ProcessInfo::ProcessInfo() {
processorsCount = 0;
}
PIIntrospection::ObjectInfo::ObjectInfo() {
queued_events = 0;
}
PIIntrospection::ProcessInfo PIIntrospection::getInfo() {
PIIntrospection::ProcessInfo ret;
PISystemInfo * si = PISystemInfo::instance();
ret.architecture = si->architecture;
ret.execCommand = si->execCommand;
ret.execDateTime = si->execDateTime;
ret.hostname = si->hostname;
ret.OS_name = si->OS_name;
ret.OS_version = si->OS_version;
ret.processorsCount = si->processorsCount;
ret.user = si->user;
ret.build_options = PIInit::buildOptions();
return ret;
}
PIVector<PIIntrospection::ObjectInfo> PIIntrospection::getObjects() {
PIVector<PIIntrospection::ObjectInfo> ret;
PIObject::mutexObjects().lock();
const PIVector<PIObject * > & ao(PIObject::objects());
ret.resize(ao.size());
for (int i = 0; i < ao.size_s(); ++i) {
ret[i].classname = PIStringAscii(ao[i]->className());
ret[i].name = ao[i]->name();
ret[i].properties = ao[i]->properties_;
ret[i].parents = ao[i]->scopeList();
ao[i]->mutex_queue.lock();
ret[i].queued_events = ao[i]->events_queue.size_s();
ao[i]->mutex_queue.unlock();
}
PIObject::mutexObjects().unlock();
return ret;
}
PIByteArray & operator <<(PIByteArray & s, const std::unordered_map<uint, PIIntrospectionContainers::Type> & v) {
PIMap<uint, PIIntrospectionContainers::Type> m;
for (typename std::unordered_map<uint, PIIntrospectionContainers::Type>::const_iterator i = v.cbegin(); i != v.cend(); ++i) {
m[i->first] = i->second;
}
s << m;
return s;
}
PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::ProcessInfo & v) {
PIChunkStream cs;
cs.add(1, v.architecture).add(2, v.execCommand).add(3, v.execDateTime).add(4, v.hostname).add(5, v.OS_name)
.add(6, v.OS_version).add(7, v.processorsCount).add(8, v.user).add(9, v.build_options);
b << cs.data();
return b;
}
PIByteArray & operator >>(PIByteArray & b, PIIntrospection::ProcessInfo & v) {
PIByteArray csba; b >> csba;
PIChunkStream cs(csba);
while (!cs.atEnd()) {
switch (cs.read()) {
case 1: cs.get(v.architecture); break;
case 2: cs.get(v.execCommand); break;
case 3: cs.get(v.execDateTime); break;
case 4: cs.get(v.hostname); break;
case 5: cs.get(v.OS_name); break;
case 6: cs.get(v.OS_version); break;
case 7: cs.get(v.processorsCount); break;
case 8: cs.get(v.user); break;
case 9: cs.get(v.build_options); break;
default: break;
}
}
return b;
}
PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::ObjectInfo & v) {
PIChunkStream cs;
cs.add(1, v.classname).add(2, v.name).add(3, v.parents).add(4, v.properties).add(5, v.queued_events);
b << cs.data();
return b;
}
PIByteArray & operator >>(PIByteArray & b, PIIntrospection::ObjectInfo & v) {
PIByteArray csba; b >> csba;
PIChunkStream cs(csba);
while (!cs.atEnd()) {
switch (cs.read()) {
case 1: cs.get(v.classname); break;
case 2: cs.get(v.name); break;
case 3: cs.get(v.parents); break;
case 4: cs.get(v.properties); break;
case 5: cs.get(v.queued_events); break;
default: break;
}
}
return b;
}
PIByteArray PIIntrospection::packInfo() {
PIByteArray ret;
ret << getInfo();
return ret;
}
void PIIntrospection::unpackInfo(PIByteArray & ba, PIIntrospection::ProcessInfo & info) {
ba >> info;
}
PIByteArray PIIntrospection::packContainers() {
PIByteArray ret;
PIIntrospectionContainers * p = PIINTROSPECTION_CONTAINERS->p;
p->mutex.lock();
std::unordered_map<uint, PIIntrospectionContainers::Type> data = p->data;
std::unordered_map<uint, std::string> typenames = p->typenames;
p->mutex.unlock();
ret << data << typenames;
return ret;
}
void PIIntrospection::unpackContainers(PIByteArray & ba, PIMap<uint, PIIntrospectionContainers::Type> & data, PIMap<uint, PIString> & typenames) {
data.clear();
typenames.clear();
ba >> data >> typenames;
}
PIByteArray PIIntrospection::packThreads() {
PIByteArray ret;
PIIntrospectionThreads * p = PIINTROSPECTION_THREADS->p;
p->mutex.lock();
ret << p->threads.values();
p->mutex.unlock();
return ret;
}
void PIIntrospection::unpackThreads(PIByteArray & ba, PIVector<PIIntrospectionThreads::ThreadInfo> & threads) {
threads.clear();
ba >> threads;
}
PIByteArray PIIntrospection::packObjects() {
PIByteArray ret;
ret << getObjects();
return ret;
}
void PIIntrospection::unpackObjects(PIByteArray & ba, PIVector<PIIntrospection::ObjectInfo> & objects) {
objects.clear();
ba >> objects;
}

View File

@@ -0,0 +1,79 @@
/*
PIP - Platform Independent Primitives
Introspection module - Base server structs
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
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, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIINTROSPECTION_SERVER_P_H
#define PIINTROSPECTION_SERVER_P_H
#include "piintrospection_containers.h"
#include "piintrospection_containers_p.h"
#include "piintrospection_threads.h"
#include "piintrospection_threads_p.h"
#include "pitime.h"
class PIIntrospection {
public:
struct ProcessInfo {
ProcessInfo();
PIString execCommand, hostname, user, OS_name, OS_version, architecture;
PIDateTime execDateTime;
int processorsCount;
PIStringList build_options;
};
struct ObjectInfo {
ObjectInfo();
PIString classname, name;
PIStringList parents;
PIMap<PIString, PIVariant> properties;
int queued_events;
};
static const uint sign;
static ProcessInfo getInfo();
static PIVector<ObjectInfo> getObjects();
static PIByteArray packInfo();
static void unpackInfo(PIByteArray & ba, ProcessInfo & info);
static PIByteArray packContainers();
static void unpackContainers(PIByteArray & ba, PIMap<uint, PIIntrospectionContainers::Type> & data, PIMap<uint, PIString> & typenames);
static PIByteArray packThreads();
static void unpackThreads(PIByteArray & ba, PIVector<PIIntrospectionThreads::ThreadInfo> & threads);
static PIByteArray packObjects();
static void unpackObjects(PIByteArray & ba, PIVector<PIIntrospection::ObjectInfo> & objects);
};
PIByteArray & operator <<(PIByteArray & s, const std::unordered_map<uint, PIIntrospectionContainers::Type> & v);
PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::ProcessInfo & v);
PIByteArray & operator >>(PIByteArray & b, PIIntrospection::ProcessInfo & v);
PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::ObjectInfo & v);
PIByteArray & operator >>(PIByteArray & b, PIIntrospection::ObjectInfo & v);
#endif // PIINTROSPECTION_SERVER_P_H

View File

@@ -45,6 +45,7 @@ class PIIntrospectionThreads;
#endif
class PIP_EXPORT PIIntrospectionThreadsInterface {
friend class PIIntrospection;
public:
__PIINTROSPECTION_SINGLETON__(Threads)