From ed6fcd4a50f3a0d84ae07a8a0011b193e00cf088 Mon Sep 17 00:00:00 2001 From: brain Date: Wed, 18 Jun 2008 18:54:25 +0000 Subject: Add the rest of the stuff for named pipe comms, including feedback information, and fix a bug in configreader that made it load the core commands every rehash git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@9913 e03df62e-2008-0410-955e-edbf42e46eb7 --- win/inspircdVC80.vcproj | 2 +- win/inspircd_namedpipe.cpp | 135 +++++++++++++++++++++++++++++++-------------- win/inspircd_namedpipe.h | 17 +++--- 3 files changed, 102 insertions(+), 52 deletions(-) (limited to 'win') diff --git a/win/inspircdVC80.vcproj b/win/inspircdVC80.vcproj index 8506ef722..c293e0466 100644 --- a/win/inspircdVC80.vcproj +++ b/win/inspircdVC80.vcproj @@ -155,7 +155,7 @@ /> +#include -void IPCThread::Run() + +IPCThread::IPCThread(InspIRCd* Instance) : Thread(), ServerInstance(Instance) +{ +} + +IPCThread::~IPCThread() { - printf("*** IPCThread::Run() *** \n"); +} + +void IPCThread::Run() +{ LPTSTR Pipename = "\\\\.\\pipe\\InspIRCdStatus"; while (GetExitFlag() == false) @@ -22,85 +32,126 @@ void IPCThread::Run() 1000, // client time-out NULL); // no security attribute - printf("*** After CreateNamedPipe *** \n"); - if (Pipe == INVALID_HANDLE_VALUE) { - printf("*** IPC failure creating named pipe: %s\n", dlerror()); - return; + SleepEx(500, 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; + 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; - ServerInstance->Threads->Mutex(true); - status << "name " << ServerInstance->Config->ServerName << std::endl; - status << "END" << std::endl; + PROCESS_MEMORY_COUNTERS MemCounters; + + 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; + 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); } } +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); - 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); + 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; + } } IPC::~IPC() diff --git a/win/inspircd_namedpipe.h b/win/inspircd_namedpipe.h index 4cd69ea0e..9985a8026 100644 --- a/win/inspircd_namedpipe.h +++ b/win/inspircd_namedpipe.h @@ -9,21 +9,20 @@ class InspIRCd; class IPCThread : public Thread { BOOL Connected; - CHAR Request[MAXBUF]; DWORD BytesRead; BOOL Success; HANDLE Pipe; InspIRCd* ServerInstance; + char status[MAXBUF]; + int result; public: - IPCThread(InspIRCd* Instance) : Thread(), ServerInstance(Instance) - { - } - - virtual ~IPCThread() - { - } - + IPCThread(InspIRCd* Instance); + virtual ~IPCThread(); virtual void Run(); + const char GetStatus(); + int GetResult(); + void ClearStatus(); + void SetResult(int newresult); }; class IPC -- cgit v1.2.3