summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/commands/cmd_stats.cpp8
-rw-r--r--src/configreader.cpp14
-rw-r--r--win/inspircdVC80.vcproj2
-rw-r--r--win/inspircd_namedpipe.cpp135
-rw-r--r--win/inspircd_namedpipe.h17
5 files changed, 118 insertions, 58 deletions
diff --git a/src/commands/cmd_stats.cpp b/src/commands/cmd_stats.cpp
index 03c48609f..1296bf08a 100644
--- a/src/commands/cmd_stats.cpp
+++ b/src/commands/cmd_stats.cpp
@@ -227,6 +227,14 @@ DllExport void DoStats(InspIRCd* ServerInstance, char statschar, User* user, str
snprintf(percent, 30, "%03.5f%%", per);
results.push_back(sn+" 249 "+user->nick+" :CPU Usage: "+percent);
}
+#else
+ PROCESS_MEMORY_COUNTERS MemCounters;
+ if (GetProcessMemoryInfo(GetCurrentProcess(), &MemCounters, sizeof(MemCounters)))
+ {
+ results.push_back(sn+" 249 "+user->nick+" :Total allocation: "+ConvToStr((MemCounters.WorkingSetSize + MemCounters.PagefileUsage) / 1024)+"K");
+ results.push_back(sn+" 249 "+user->nick+" :Pagefile usage: "+ConvToStr(MemCounters.PagefileUsage / 1024)+"K");
+ results.push_back(sn+" 249 "+user->nick+" :Page faults: "+ConvToStr(MemCounters.PageFaultCount));
+ }
#endif
}
break;
diff --git a/src/configreader.cpp b/src/configreader.cpp
index ad0e972f9..c492f6934 100644
--- a/src/configreader.cpp
+++ b/src/configreader.cpp
@@ -1302,12 +1302,14 @@ void ServerConfig::Read(bool bail, User* user)
}
- /** Note: This is safe, the method checks for user == NULL */
- ServerInstance->Threads->Mutex(true);
- ServerInstance->Parser->SetupCommandTable(user);
- ServerInstance->Threads->Mutex(false);
-
- if (!bail)
+ if (bail)
+ {
+ /** Note: This is safe, the method checks for user == NULL */
+ ServerInstance->Threads->Mutex(true);
+ ServerInstance->Parser->SetupCommandTable(user);
+ ServerInstance->Threads->Mutex(false);
+ }
+ else
{
if (user)
user->WriteServ("NOTICE %s :*** Successfully rehashed server.", user->nick.c_str());
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 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="dbghelp.lib ws2_32.lib mswsock.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib"
+ AdditionalDependencies="psapi.lib ws2_32.lib mswsock.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib"
OutputFile="$(OutDir)/inspircd.exe"
LinkIncremental="1"
EmbedManagedResourceFile="inspircd.ico"
diff --git a/win/inspircd_namedpipe.cpp b/win/inspircd_namedpipe.cpp
index 9a960e4c3..30aab9cd4 100644
--- a/win/inspircd_namedpipe.cpp
+++ b/win/inspircd_namedpipe.cpp
@@ -1,12 +1,22 @@
#include "inspircd.h"
#include "threadengine.h"
#include "inspircd_namedpipe.h"
+#include "exitcodes.h"
#include <windows.h>
+#include <psapi.h>
-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