summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--VC2008/MCServer.vcproj16
-rw-r--r--VC2010/MCServer.vcxproj2
-rw-r--r--VC2010/MCServer.vcxproj.filters2
-rw-r--r--makefile7
-rw-r--r--source/cIsThread.cpp148
-rw-r--r--source/cIsThread.h77
6 files changed, 247 insertions, 5 deletions
diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj
index ef5f1d3c1..1698616c4 100644
--- a/VC2008/MCServer.vcproj
+++ b/VC2008/MCServer.vcproj
@@ -436,10 +436,6 @@
>
</File>
<File
- RelativePath="..\source\cSign.h"
- >
- </File>
- <File
RelativePath="..\source\cSimulator.cpp"
>
</File>
@@ -1291,6 +1287,10 @@
>
</File>
<File
+ RelativePath="..\source\cSign.h"
+ >
+ </File>
+ <File
RelativePath="..\source\cSignEntity.cpp"
>
</File>
@@ -1435,6 +1435,14 @@
>
</File>
<File
+ RelativePath="..\source\cIsThread.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\source\cIsThread.h"
+ >
+ </File>
+ <File
RelativePath="..\source\cMakeDir.cpp"
>
</File>
diff --git a/VC2010/MCServer.vcxproj b/VC2010/MCServer.vcxproj
index 3698a757d..4cdd9d15c 100644
--- a/VC2010/MCServer.vcxproj
+++ b/VC2010/MCServer.vcxproj
@@ -330,6 +330,7 @@
<ClCompile Include="..\Source\cGroup.cpp" />
<ClCompile Include="..\Source\cGroupManager.cpp" />
<ClCompile Include="..\Source\cHeartBeat.cpp" />
+ <ClCompile Include="..\source\cIsThread.cpp" />
<ClCompile Include="..\source\cItem.cpp" />
<ClCompile Include="..\source\cLavaSimulator.cpp" />
<ClCompile Include="..\Source\cLuaCommandBinder.cpp" />
@@ -496,6 +497,7 @@
<ClInclude Include="..\Source\cGroup.h" />
<ClInclude Include="..\Source\cGroupManager.h" />
<ClInclude Include="..\Source\cHeartBeat.h" />
+ <ClInclude Include="..\source\cIsThread.h" />
<ClInclude Include="..\Source\cLadder.h" />
<ClInclude Include="..\source\cLavaSimulator.h" />
<ClInclude Include="..\Source\cLuaCommandBinder.h" />
diff --git a/VC2010/MCServer.vcxproj.filters b/VC2010/MCServer.vcxproj.filters
index d605360b0..031f6588a 100644
--- a/VC2010/MCServer.vcxproj.filters
+++ b/VC2010/MCServer.vcxproj.filters
@@ -910,6 +910,7 @@
<ClCompile Include="..\source\Globals.cpp" />
<ClCompile Include="..\source\cFile.cpp" />
<ClCompile Include="..\source\StringUtils.cpp" />
+ <ClCompile Include="..\source\cIsThread.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\source\cServer.h">
@@ -1401,6 +1402,7 @@
<ClInclude Include="..\source\Globals.h" />
<ClInclude Include="..\source\cFile.h" />
<ClInclude Include="..\source\StringUtils.h" />
+ <ClInclude Include="..\source\cIsThread.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\source\AllToLua.pkg">
diff --git a/makefile b/makefile
index 0f92fe58a..bf183922f 100644
--- a/makefile
+++ b/makefile
@@ -248,7 +248,8 @@ MCServer : \
build/cItem.o\
build/cPlugin_NewLua.o\
build/cWebPlugin_Lua.o\
- build/StringUtils.o
+ build/StringUtils.o\
+ build/cIsThread.o
$(CC) $(LNK_OPTIONS) \
build/json_reader.o\
build/json_value.o\
@@ -460,6 +461,7 @@ MCServer : \
build/cPlugin_NewLua.o\
build/cWebPlugin_Lua.o\
build/StringUtils.o\
+ build/cIsThread.o\
-o MCServer
clean :
@@ -1534,4 +1536,7 @@ build/cWebPlugin_Lua.o : source/cWebPlugin_Lua.cpp
build/StringUtils.o : source/StringUtils.cpp
$(CC) $(CC_OPTIONS) source/StringUtils.cpp -c $(INCLUDE) -o build/StringUtils.o
+build/cIsThread.o : source/cIsThread.cpp
+ $(CC) $(CC_OPTIONS) source/cIsThread.cpp -c $(INCLUDE) -o build/cIsThread.o
+
##### END RUN ####
diff --git a/source/cIsThread.cpp b/source/cIsThread.cpp
new file mode 100644
index 000000000..cee4d4477
--- /dev/null
+++ b/source/cIsThread.cpp
@@ -0,0 +1,148 @@
+
+// cIsThread.cpp
+
+// Implements the cIsThread class representing an OS-independent wrapper for a class that implements a thread.
+// This class will eventually suupersede the old cThread class
+
+#include "Globals.h"
+
+#include "cIsThread.h"
+
+
+
+
+
+// When in MSVC, the debugger provides "thread naming" by catching special exceptions. Interface here:
+#ifdef _MSC_VER
+//
+// Usage: SetThreadName (-1, "MainThread");
+//
+
+static void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName)
+{
+ struct
+ {
+ DWORD dwType; // must be 0x1000
+ LPCSTR szName; // pointer to name (in user addr space)
+ DWORD dwThreadID; // thread ID (-1=caller thread)
+ DWORD dwFlags; // reserved for future use, must be zero
+ } info;
+
+ info.dwType = 0x1000;
+ info.szName = szThreadName;
+ info.dwThreadID = dwThreadID;
+ info.dwFlags = 0;
+
+ __try
+ {
+ RaiseException(0x406D1388, 0, sizeof(info) / sizeof(DWORD), (DWORD *)&info);
+ }
+ __except(EXCEPTION_CONTINUE_EXECUTION)
+ {
+ }
+}
+#endif // _MSC_VER
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// cIsThread:
+
+cIsThread::cIsThread(const AString & iThreadName) :
+ mThreadName(iThreadName),
+ mShouldTerminate(false),
+ #ifdef _WIN32
+ mHandle(NULL)
+ #else // _WIN32
+ mHasStarted(false)
+ #endif // else _WIN32
+{
+}
+
+
+
+
+
+cIsThread::~cIsThread()
+{
+ Wait();
+}
+
+
+
+
+
+bool cIsThread::Start(void)
+{
+ #ifdef _WIN32
+ assert(mHandle == NULL); // Has already started one thread?
+
+ // Create the thread suspended, so that the mHandle variable is valid in the thread procedure
+ DWORD ThreadID = 0;
+ HANDLE mHandle = CreateThread(NULL, 0, thrExecute, this, CREATE_SUSPENDED, &ThreadID);
+ if (mHandle == NULL)
+ {
+ LOGERROR("ERROR: Could not create thread \"%s\", GLE = %d!", mThreadName.c_str(), GetLastError());
+ return false;
+ }
+ ResumeThread(mHandle);
+
+ #if defined(_DEBUG) && defined(_MSC_VER)
+ // Thread naming is available only in MSVC
+ if (!mThreadName.empty())
+ {
+ SetThreadName(ThreadID, mThreadName.c_str());
+ }
+ #endif // _DEBUG and _MSC_VER
+
+ #else // _WIN32
+ assert(!mHasStarted);
+
+ if (pthread_create(&mHandle, NULL, thrExecute, this))
+ {
+ LOGERROR("ERROR: Could not create thread \"%s\", !", mThreadName.c_str());
+ return false;
+ }
+ #endif // else _WIN32
+
+ return true;
+}
+
+
+
+
+
+bool cIsThread::Wait(void)
+{
+ #ifdef _WIN32
+
+ if (mHandle == NULL)
+ {
+ return true;
+ }
+ LOG("Waiting for thread \"%s\" to terminate.", mThreadName.c_str());
+ int res = WaitForSingleObject(mHandle, INFINITE);
+ mHandle = NULL;
+ LOG("Thread \"%s\" %s terminated, GLE = %d", mThreadName.c_str(), (res == WAIT_OBJECT_0) ? "" : "not", GetLastError());
+ return (res == WAIT_OBJECT_0);
+
+ #else // _WIN32
+
+ if (!mHasStarted)
+ {
+ return true;
+ }
+ LOG("Waiting for thread \"%s\" to terminate.", mThreadName.c_str());
+ int res = pthread_join(mHandle, NULL);
+ mHasStarted = false;
+ LOG("Thread \"%s\" %s terminated, errno = %d", mThreadName.c_str(), (res == 0) ? "" : "not", errno);
+ return (res == 0);
+
+ #endif // else _WIN32
+}
+
+
+
+
diff --git a/source/cIsThread.h b/source/cIsThread.h
new file mode 100644
index 000000000..f46d7f065
--- /dev/null
+++ b/source/cIsThread.h
@@ -0,0 +1,77 @@
+
+// cIsThread.h
+
+// Interfaces to the cIsThread class representing an OS-independent wrapper for a class that implements a thread.
+// This class will eventually suupersede the old cThread class
+
+/*
+Usage:
+To have a new thread, declare a class descending from cIsClass.
+Then override its Execute() method to provide your thread processing.
+In the descending class' constructor call the Start() method to start the thread once you're finished with initialization.
+*/
+
+
+
+
+
+#pragma once
+#ifndef CISTHREAD_H_INCLUDED
+#define CISTHREAD_H_INCLUDED
+
+
+
+
+
+class cIsThread
+{
+protected:
+ virtual void Execute(void) = 0; // This function is called in the new thread's context
+
+ volatile bool mShouldTerminate; // The overriden Execute() method should check this periodically and terminate if this is true
+
+public:
+ cIsThread(const AString & iThreadName);
+ ~cIsThread();
+
+ bool Start(void); // Starts the thread
+ bool Wait(void); // Waits for the thread to finish
+
+private:
+ AString mThreadName;
+ cEvent mEvent; // This event is set when the thread begins executing
+
+ #ifdef _WIN32
+
+ HANDLE mHandle;
+
+ static DWORD_PTR __stdcall thrExecute(LPVOID iParam)
+ {
+ ((cIsThread *)iParam)->Execute();
+ return 0;
+ }
+
+ #else // _WIN32
+
+ pthread_t mHandle;
+ bool mHasStarted;
+
+ static void * thrExecute(void * iParam)
+ {
+ ((cIsThread *)iParam)->Execute();
+ return NULL;
+ }
+
+ #endif // else _WIN32
+
+} ;
+
+
+
+
+
+#endif // CISTHREAD_H_INCLUDED
+
+
+
+