X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=win%2Finspircd_namedpipe.cpp;h=93d7c423a1cbeb7690bebbf8674b7e9d23e72fd4;hb=7b08be5752bb91d495f324f97b346976d669ad90;hp=9a960e4c3b3f93528292bc7aa7c1ae8dcec8bc16;hpb=874c398ad9e185cca26011317a2f7ecf2623d214;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/win/inspircd_namedpipe.cpp b/win/inspircd_namedpipe.cpp index 9a960e4c3..93d7c423a 100644 --- a/win/inspircd_namedpipe.cpp +++ b/win/inspircd_namedpipe.cpp @@ -1,110 +1,177 @@ #include "inspircd.h" #include "threadengine.h" #include "inspircd_namedpipe.h" +#include "exitcodes.h" #include +#include -void IPCThread::Run() + +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(); +} - printf("*** IPCThread::Run() *** \n"); +void IPCThread::Run() +{ LPTSTR Pipename = "\\\\.\\pipe\\InspIRCdStatus"; - while (GetExitFlag() == false) + 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 - - printf("*** After CreateNamedPipe *** \n"); + 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) { - printf("*** IPC failure creating named pipe: %s\n", dlerror()); - return; + SleepEx(10, true); + continue; } - printf("*** After check, exit flag=%d *** \n", GetExitFlag()); - - printf("*** Loop *** \n"); Connected = ConnectNamedPipe(Pipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); - printf("*** After ConnectNamedPipe *** \n"); - if (Connected) { - ServerInstance->Logs->Log("IPC", DEBUG, "About to ReadFile from pipe"); - 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'; - ServerInstance->Logs->Log("IPC", DEBUG, "Received from IPC: %s", Request); - //printf("Data Received: %s\n",chRequest); - if (!Success || !BytesRead) { - printf("*** IPC failure reading client named pipe: %s\n", dlerror()); + CloseHandle(Pipe); continue; } - std::stringstream status; - DWORD Written = 0; - ServerInstance->Threads->Mutex(true); + const char oldrequest = this->GetStatus(); + + /* Wait for main thread to pick up status change */ + while (this->GetStatus()) + SleepEx(10, true); - status << "name " << ServerInstance->Config->ServerName << std::endl; - status << "END" << std::endl; + 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; + } - ServerInstance->Threads->Mutex(false); + stat << "END" << std::endl; /* This is a blocking call and will succeed, so long as the client doesnt disconnect */ - Success = WriteFile(Pipe, status.str().data(), status.str().length(), &Written, NULL); + Success = WriteFile(Pipe, stat.str().data(), stat.str().length(), &Written, NULL); FlushFileBuffers(Pipe); DisconnectNamedPipe(Pipe); } - else - { - // The client could not connect. - printf("*** IPC failure connecting named pipe: %s\n", dlerror()); - } - - printf("*** sleep for next client ***\n"); - printf("*** Closing pipe handle\n"); CloseHandle(Pipe); } } -IPC::IPC(InspIRCd* Srv) : ServerInstance(Srv) -{ - /* The IPC pipe is threaded */ - thread = new IPCThread(Srv); - Srv->Threads->Create(thread); - printf("*** CREATE IPC THREAD ***\n"); -} - -void IPC::Check() -{ - ServerInstance->Threads->Mutex(true); - - /* Check the state of the thread, safe in here */ - - - - ServerInstance->Threads->Mutex(false); -} - -IPC::~IPC() -{ - thread->SetExitFlag(); - delete thread; -} \ No newline at end of file +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->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; + } +} + +IPC::~IPC() +{ + thread->SetExitFlag(); + delete thread; +}