mirror of
https://github.com/inspircd/inspircd.git
synced 2025-03-10 11:09:04 -04:00
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@10343 e03df62e-2008-0410-955e-edbf42e46eb7
178 lines
4.7 KiB
C++
178 lines
4.7 KiB
C++
#include "inspircd.h"
|
|
#include "threadengine.h"
|
|
#include "inspircd_namedpipe.h"
|
|
#include "exitcodes.h"
|
|
#include <windows.h>
|
|
#include <psapi.h>
|
|
|
|
|
|
IPCThread::IPCThread(InspIRCd* Instance) : Thread(), ServerInstance(Instance)
|
|
{
|
|
if (!initwmi())
|
|
ServerInstance->Logs->Log("IPC", DEBUG, "Could not initialise WMI. CPU percantage reports will not be available.");
|
|
}
|
|
|
|
IPCThread::~IPCThread()
|
|
{
|
|
donewmi();
|
|
}
|
|
|
|
void IPCThread::Run()
|
|
{
|
|
LPTSTR Pipename = "\\\\.\\pipe\\InspIRCdStatus";
|
|
|
|
while (GetExitFlag() == false)
|
|
{
|
|
Pipe = CreateNamedPipe (Pipename,
|
|
PIPE_ACCESS_DUPLEX, // read/write access
|
|
PIPE_TYPE_MESSAGE | // message type pipe
|
|
PIPE_READMODE_MESSAGE | // message-read mode
|
|
PIPE_WAIT, // blocking mode
|
|
PIPE_UNLIMITED_INSTANCES, // max. instances
|
|
MAXBUF, // output buffer size
|
|
MAXBUF, // input buffer size
|
|
1000, // client time-out
|
|
NULL); // no security attribute
|
|
|
|
if (Pipe == INVALID_HANDLE_VALUE)
|
|
{
|
|
SleepEx(10, true);
|
|
continue;
|
|
}
|
|
|
|
Connected = ConnectNamedPipe(Pipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
|
|
|
|
if (Connected)
|
|
{
|
|
Success = ReadFile (Pipe, // handle to pipe
|
|
this->status, // buffer to receive data
|
|
1, // size of buffer
|
|
&BytesRead, // number of bytes read
|
|
NULL); // not overlapped I/O
|
|
|
|
if (!Success || !BytesRead)
|
|
{
|
|
CloseHandle(Pipe);
|
|
continue;
|
|
}
|
|
|
|
const char oldrequest = this->GetStatus();
|
|
|
|
/* Wait for main thread to pick up status change */
|
|
while (this->GetStatus())
|
|
SleepEx(10, true);
|
|
|
|
std::stringstream stat;
|
|
DWORD Written = 0;
|
|
float kbitpersec_in, kbitpersec_out, kbitpersec_total;
|
|
|
|
PROCESS_MEMORY_COUNTERS MemCounters;
|
|
|
|
ServerInstance->SE->GetStats(kbitpersec_in, kbitpersec_out, kbitpersec_total);
|
|
|
|
bool HaveMemoryStats = GetProcessMemoryInfo(GetCurrentProcess(), &MemCounters, sizeof(MemCounters));
|
|
|
|
stat << "name " << ServerInstance->Config->ServerName << std::endl;
|
|
stat << "gecos " << ServerInstance->Config->ServerDesc << std::endl;
|
|
stat << "numlocalusers " << ServerInstance->Users->LocalUserCount() << std::endl;
|
|
stat << "numusers " << ServerInstance->Users->clientlist->size() << std::endl;
|
|
stat << "numchannels " << ServerInstance->chanlist->size() << std::endl;
|
|
stat << "numopers " << ServerInstance->Users->OperCount() << std::endl;
|
|
stat << "timestamp " << ServerInstance->Time() << std::endl;
|
|
stat << "pid " << GetProcessId(GetCurrentProcess()) << std::endl;
|
|
stat << "request " << oldrequest << std::endl;
|
|
stat << "result " << this->GetResult() << std::endl;
|
|
stat << "kbitspersectotal " << kbitpersec_total << std::endl;
|
|
stat << "kbitspersecout " << kbitpersec_out << std::endl;
|
|
stat << "kbitspersecin " << kbitpersec_in << std::endl;
|
|
stat << "uptime " << ServerInstance->Time() - ServerInstance->startup_time << std::endl;
|
|
stat << "cpu " << getcpu() << std::endl;
|
|
if (HaveMemoryStats)
|
|
{
|
|
stat << "workingset " << MemCounters.WorkingSetSize << std::endl;
|
|
stat << "pagefile " << MemCounters.PagefileUsage << std::endl;
|
|
stat << "pagefaults " << MemCounters.PageFaultCount << std::endl;
|
|
}
|
|
|
|
stat << "END" << std::endl;
|
|
|
|
/* This is a blocking call and will succeed, so long as the client doesnt disconnect */
|
|
Success = WriteFile(Pipe, stat.str().data(), stat.str().length(), &Written, NULL);
|
|
|
|
FlushFileBuffers(Pipe);
|
|
DisconnectNamedPipe(Pipe);
|
|
}
|
|
CloseHandle(Pipe);
|
|
}
|
|
}
|
|
|
|
const char IPCThread::GetStatus()
|
|
{
|
|
return *status;
|
|
}
|
|
|
|
void IPCThread::ClearStatus()
|
|
{
|
|
*status = '\0';
|
|
}
|
|
|
|
int IPCThread::GetResult()
|
|
{
|
|
return result;
|
|
}
|
|
|
|
void IPCThread::SetResult(int newresult)
|
|
{
|
|
result = newresult;
|
|
}
|
|
|
|
|
|
IPC::IPC(InspIRCd* Srv) : ServerInstance(Srv)
|
|
{
|
|
/* The IPC pipe is threaded */
|
|
thread = new IPCThread(Srv);
|
|
Srv->Threads->Create(thread);
|
|
}
|
|
|
|
void IPC::Check()
|
|
{
|
|
switch (thread->GetStatus())
|
|
{
|
|
case 'N':
|
|
/* No-Operation */
|
|
thread->SetResult(0);
|
|
thread->ClearStatus();
|
|
break;
|
|
case '1':
|
|
/* Rehash */
|
|
ServerInstance->Rehash("due to rehash command from GUI");
|
|
thread->SetResult(0);
|
|
thread->ClearStatus();
|
|
break;
|
|
case '2':
|
|
/* Shutdown */
|
|
thread->SetResult(0);
|
|
thread->ClearStatus();
|
|
ServerInstance->Exit(EXIT_STATUS_NOERROR);
|
|
break;
|
|
case '3':
|
|
/* Restart */
|
|
thread->SetResult(0);
|
|
thread->ClearStatus();
|
|
ServerInstance->Restart("Restarting due to command from GUI");
|
|
break;
|
|
case '4':
|
|
/* Toggle debug */
|
|
thread->SetResult(0);
|
|
thread->ClearStatus();
|
|
ServerInstance->Config->forcedebug = !ServerInstance->Config->forcedebug;
|
|
break;
|
|
}
|
|
}
|
|
|
|
IPC::~IPC()
|
|
{
|
|
thread->SetExitFlag();
|
|
delete thread;
|
|
}
|