X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=win%2Finspircd_namedpipe.cpp;h=93d7c423a1cbeb7690bebbf8674b7e9d23e72fd4;hb=1662f21eedf91c49ac97333f72f494c36895803e;hp=6610d1f5c24a33d0e53612aedbc89a6e9e4663dd;hpb=afe99da316b6f63900df2bd8711ab515f4977f6a;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/win/inspircd_namedpipe.cpp b/win/inspircd_namedpipe.cpp index 6610d1f5c..93d7c423a 100644 --- a/win/inspircd_namedpipe.cpp +++ b/win/inspircd_namedpipe.cpp @@ -1,76 +1,177 @@ #include "inspircd.h" #include "threadengine.h" #include "inspircd_namedpipe.h" +#include "exitcodes.h" #include +#include + + +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"; - 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) - return; - - while (GetExitFlag() == false) + while (GetExitFlag() == false) { - // Trying connectnamedpipe in sample for CreateNamedPipe - // Wait for the client to connect; if it succeeds, - // the function returns a nonzero value. If the function returns - // zero, GetLastError returns ERROR_PIPE_CONNECTED. + 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 - Request, // buffer to receive data - MAXBUF, // size of buffer + this->status, // buffer to receive data + 1, // size of buffer &BytesRead, // number of bytes read NULL); // not overlapped I/O - Request[BytesRead] = '\0'; - //printf("Data Received: %s\n",chRequest); - if (!Success || !BytesRead) - break; + { + 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); } - else - { - // The client could not connect. - CloseHandle(Pipe); - } + CloseHandle(Pipe); + } +} + +const char IPCThread::GetStatus() +{ + return *status; +} + +void IPCThread::ClearStatus() +{ + *status = '\0'; +} + +int IPCThread::GetResult() +{ + return result; +} - SleepEx(100, FALSE); +void IPCThread::SetResult(int newresult) +{ + result = newresult; +} + + +IPC::IPC(InspIRCd* Srv) : ServerInstance(Srv) +{ + /* The IPC pipe is threaded */ + thread = new IPCThread(Srv); + Srv->Threads->Start(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; } - CloseHandle(Pipe); } -IPC::IPC(InspIRCd* Srv) : ServerInstance(Srv) -{ - /* The IPC pipe is threaded */ - thread = new IPCThread(Srv); - Srv->Threads->Create(thread); -} - -void IPC::Check() -{ -} - -IPC::~IPC() -{ - thread->SetExitFlag(); - delete thread; -} \ No newline at end of file +IPC::~IPC() +{ + thread->SetExitFlag(); + delete thread; +}