]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - win/inspircd_namedpipe.cpp
Windows compile fixes
[user/henk/code/inspircd.git] / win / inspircd_namedpipe.cpp
index 6610d1f5c24a33d0e53612aedbc89a6e9e4663dd..36724366010575c741a3cc7e2702c8562e735f26 100644 (file)
 #include "inspircd.h"\r
 #include "threadengine.h"\r
 #include "inspircd_namedpipe.h"\r
+#include "exitcodes.h"\r
 #include <windows.h>\r
+#include <psapi.h>\r
+\r
+\r
+IPCThread::IPCThread(InspIRCd* Instance) : Thread(), ServerInstance(Instance)\r
+{\r
+       if (!initwmi())\r
+               ServerInstance->Logs->Log("IPC", DEBUG, "Could not initialise WMI. CPU percantage reports will not be available.");\r
+}\r
+\r
+IPCThread::~IPCThread()\r
+{\r
+       donewmi();\r
+}\r
 \r
 void IPCThread::Run()\r
 {\r
        LPTSTR Pipename = "\\\\.\\pipe\\InspIRCdStatus";\r
 \r
-       Pipe = CreateNamedPipe ( Pipename,\r
-                                          PIPE_ACCESS_DUPLEX, // read/write access\r
-                                          PIPE_TYPE_MESSAGE | // message type pipe\r
-                                          PIPE_READMODE_MESSAGE | // message-read mode\r
-                                          PIPE_WAIT, // blocking mode\r
-                                          PIPE_UNLIMITED_INSTANCES, // max. instances\r
-                                          MAXBUF, // output buffer size\r
-                                          MAXBUF, // input buffer size\r
-                                          1000, // client time-out\r
-                                          NULL); // no security attribute\r
-\r
-       if (Pipe == INVALID_HANDLE_VALUE)\r
-               return;\r
-\r
-       while (GetExitFlag() == false)
+       while (GetExitFlag() == false)\r
        {\r
-               // Trying connectnamedpipe in sample for CreateNamedPipe\r
-               // Wait for the client to connect; if it succeeds,\r
-               // the function returns a nonzero value. If the function returns\r
-               // zero, GetLastError returns ERROR_PIPE_CONNECTED.\r
+               Pipe = CreateNamedPipe (Pipename,\r
+                                       PIPE_ACCESS_DUPLEX, // read/write access\r
+                                       PIPE_TYPE_MESSAGE | // message type pipe\r
+                                       PIPE_READMODE_MESSAGE | // message-read mode\r
+                                       PIPE_WAIT, // blocking mode\r
+                                       PIPE_UNLIMITED_INSTANCES, // max. instances\r
+                                       MAXBUF, // output buffer size\r
+                                       MAXBUF, // input buffer size\r
+                                       1000, // client time-out\r
+                                       NULL); // no security attribute\r
+\r
+               if (Pipe == INVALID_HANDLE_VALUE)\r
+               {\r
+                       SleepEx(10, true);\r
+                       continue;\r
+               }\r
 \r
                Connected = ConnectNamedPipe(Pipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);\r
 \r
                if (Connected)\r
                {\r
                        Success = ReadFile (Pipe, // handle to pipe\r
-                               Request, // buffer to receive data\r
-                               MAXBUF, // size of buffer\r
+                               this->status, // buffer to receive data\r
+                               1, // size of buffer\r
                                &BytesRead, // number of bytes read\r
                                NULL); // not overlapped I/O\r
 \r
-                       Request[BytesRead] = '\0';\r
-                       //printf("Data Received: %s\n",chRequest);\r
-\r
                        if (!Success || !BytesRead)\r
-                               break;\r
+                       {\r
+                               CloseHandle(Pipe);\r
+                               continue;\r
+                       }\r
+\r
+                       const char oldrequest = this->GetStatus();\r
+\r
+                       /* Wait for main thread to pick up status change */\r
+                       while (this->GetStatus())\r
+                               SleepEx(10, true);\r
+\r
+                       std::stringstream stat;\r
+                       DWORD Written = 0;\r
+                       float kbitpersec_in, kbitpersec_out, kbitpersec_total;\r
+\r
+                       PROCESS_MEMORY_COUNTERS MemCounters;\r
+\r
+                       ServerInstance->SE->GetStats(kbitpersec_in, kbitpersec_out, kbitpersec_total);\r
+\r
+                       bool HaveMemoryStats = GetProcessMemoryInfo(GetCurrentProcess(), &MemCounters, sizeof(MemCounters));\r
+\r
+                       stat << "name " << ServerInstance->Config->ServerName << std::endl;\r
+                       stat << "gecos " << ServerInstance->Config->ServerDesc << std::endl;\r
+                       stat << "numlocalusers " << ServerInstance->Users->LocalUserCount() << std::endl;\r
+                       stat << "numusers " << ServerInstance->Users->clientlist->size() << std::endl;\r
+                       stat << "numchannels " << ServerInstance->chanlist->size() << std::endl;\r
+                       stat << "numopers " << ServerInstance->Users->OperCount() << std::endl;\r
+                       stat << "timestamp " << ServerInstance->Time() << std::endl;\r
+                       stat << "pid " << GetProcessId(GetCurrentProcess()) << std::endl;\r
+                       stat << "request " << oldrequest << std::endl;\r
+                       stat << "result " << this->GetResult() << std::endl;\r
+                       stat << "kbitspersectotal " << kbitpersec_total << std::endl;\r
+                       stat << "kbitspersecout " << kbitpersec_out << std::endl;\r
+                       stat << "kbitspersecin " << kbitpersec_in << std::endl;\r
+                       stat << "uptime " << ServerInstance->Time() - ServerInstance->startup_time << std::endl;\r
+                       stat << "cpu " << getcpu() << std::endl;\r
+                       if (HaveMemoryStats)\r
+                       {\r
+                               stat << "workingset " << MemCounters.WorkingSetSize << std::endl;\r
+                               stat << "pagefile " << MemCounters.PagefileUsage << std::endl;\r
+                               stat << "pagefaults " << MemCounters.PageFaultCount << std::endl;\r
+                       }\r
+\r
+                       stat << "END" << std::endl;\r
+\r
+                       /* This is a blocking call and will succeed, so long as the client doesnt disconnect */\r
+                       Success = WriteFile(Pipe, stat.str().data(), stat.str().length(), &Written, NULL);\r
 \r
                        FlushFileBuffers(Pipe);\r
                        DisconnectNamedPipe(Pipe);\r
                }\r
-               else\r
-               {\r
-                       // The client could not connect.\r
-                       CloseHandle(Pipe);\r
-               }\r
+               CloseHandle(Pipe);\r
+       }\r
+}\r
+\r
+const  char IPCThread::GetStatus()\r
+{\r
+       return *status;\r
+}\r
+\r
+void IPCThread::ClearStatus()\r
+{\r
+       *status = '\0';\r
+}\r
+\r
+int IPCThread::GetResult()\r
+{\r
+       return result;\r
+}\r
 \r
-               SleepEx(100, FALSE);\r
+void IPCThread::SetResult(int newresult)\r
+{\r
+       result = newresult;\r
+}\r
+\r
+\r
+IPC::IPC(InspIRCd* Srv) : ServerInstance(Srv)\r
+{\r
+       /* The IPC pipe is threaded */\r
+       thread = new IPCThread(Srv);\r
+       Srv->Threads->Create(thread);\r
+}\r
+\r
+void IPC::Check()\r
+{\r
+       switch (thread->GetStatus())\r
+       {\r
+               case 'N':\r
+                       /* No-Operation */\r
+                       thread->SetResult(0);\r
+                       thread->ClearStatus();\r
+               break;\r
+               case '1':\r
+                       /* Rehash */\r
+                       ServerInstance->Rehash("due to rehash command from GUI");\r
+                       thread->SetResult(0);\r
+                       thread->ClearStatus();\r
+               break;\r
+               case '2':\r
+                       /* Shutdown */\r
+                       thread->SetResult(0);\r
+                       thread->ClearStatus();\r
+                       ServerInstance->Exit(EXIT_STATUS_NOERROR);\r
+               break;\r
+               case '3':\r
+                       /* Restart */\r
+                       thread->SetResult(0);\r
+                       thread->ClearStatus();\r
+                       ServerInstance->Restart("Restarting due to command from GUI");\r
+               break;\r
+               case '4':\r
+                       /* Toggle debug */\r
+                       thread->SetResult(0);\r
+                       thread->ClearStatus();\r
+                       ServerInstance->Config->forcedebug = !ServerInstance->Config->forcedebug;\r
+               break;\r
        }\r
-       CloseHandle(Pipe);\r
 }\r
 \r
-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()\r
+{\r
+       thread->SetExitFlag();\r
+       delete thread;\r
+}\r