1 #include "inspircd.h"
\r
2 #include "threadengine.h"
\r
3 #include "inspircd_namedpipe.h"
\r
4 #include "exitcodes.h"
\r
9 IPCThread::IPCThread(InspIRCd* Instance) : Thread(), ServerInstance(Instance)
\r
13 IPCThread::~IPCThread()
\r
18 void IPCThread::Run()
\r
20 LPTSTR Pipename = "\\\\.\\pipe\\InspIRCdStatus";
\r
22 while (GetExitFlag() == false)
24 Pipe = CreateNamedPipe (Pipename,
\r
25 PIPE_ACCESS_DUPLEX, // read/write access
\r
26 PIPE_TYPE_MESSAGE | // message type pipe
\r
27 PIPE_READMODE_MESSAGE | // message-read mode
\r
28 PIPE_WAIT, // blocking mode
\r
29 PIPE_UNLIMITED_INSTANCES, // max. instances
\r
30 MAXBUF, // output buffer size
\r
31 MAXBUF, // input buffer size
\r
32 1000, // client time-out
\r
33 NULL); // no security attribute
\r
35 if (Pipe == INVALID_HANDLE_VALUE)
\r
41 Connected = ConnectNamedPipe(Pipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
\r
45 Success = ReadFile (Pipe, // handle to pipe
\r
46 this->status, // buffer to receive data
\r
47 1, // size of buffer
\r
48 &BytesRead, // number of bytes read
\r
49 NULL); // not overlapped I/O
\r
51 if (!Success || !BytesRead)
\r
57 const char oldrequest = this->GetStatus();
\r
59 /* Wait for main thread to pick up status change */
\r
60 while (this->GetStatus())
\r
63 std::stringstream stat;
\r
66 PROCESS_MEMORY_COUNTERS MemCounters;
\r
68 bool HaveMemoryStats = GetProcessMemoryInfo(GetCurrentProcess(), &MemCounters, sizeof(MemCounters));
\r
70 stat << "name " << ServerInstance->Config->ServerName << std::endl;
\r
71 stat << "gecos " << ServerInstance->Config->ServerDesc << std::endl;
\r
72 stat << "numlocalusers " << ServerInstance->Users->LocalUserCount() << std::endl;
\r
73 stat << "numusers " << ServerInstance->Users->clientlist->size() << std::endl;
\r
74 stat << "numchannels " << ServerInstance->chanlist->size() << std::endl;
\r
75 stat << "numopers " << ServerInstance->Users->OperCount() << std::endl;
\r
76 stat << "timestamp " << ServerInstance->Time() << std::endl;
\r
77 stat << "pid " << GetProcessId(GetCurrentProcess()) << std::endl;
\r
78 stat << "request " << oldrequest << std::endl;
\r
79 stat << "result " << this->GetResult() << std::endl;
\r
80 if (HaveMemoryStats)
\r
82 stat << "workingset " << MemCounters.WorkingSetSize << std::endl;
\r
83 stat << "pagefile " << MemCounters.PagefileUsage << std::endl;
\r
84 stat << "pagefaults " << MemCounters.PageFaultCount << std::endl;
\r
87 stat << "END" << std::endl;
\r
89 /* This is a blocking call and will succeed, so long as the client doesnt disconnect */
\r
90 Success = WriteFile(Pipe, stat.str().data(), stat.str().length(), &Written, NULL);
\r
92 FlushFileBuffers(Pipe);
\r
93 DisconnectNamedPipe(Pipe);
\r
99 const char IPCThread::GetStatus()
\r
104 void IPCThread::ClearStatus()
\r
109 int IPCThread::GetResult()
\r
114 void IPCThread::SetResult(int newresult)
\r
116 result = newresult;
\r
120 IPC::IPC(InspIRCd* Srv) : ServerInstance(Srv)
122 /* The IPC pipe is threaded */
123 thread = new IPCThread(Srv);
124 Srv->Threads->Create(thread);
129 switch (thread->GetStatus())
133 thread->SetResult(0);
134 thread->ClearStatus();
138 ServerInstance->Rehash("due to rehash command from GUI");
139 thread->SetResult(0);
140 thread->ClearStatus();
144 thread->SetResult(0);
145 thread->ClearStatus();
146 ServerInstance->Exit(EXIT_STATUS_NOERROR);
150 thread->SetResult(0);
151 thread->ClearStatus();
152 ServerInstance->Restart("Restarting due to command from GUI");
159 thread->SetExitFlag();