summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@drink-coca-cola.info>2010-05-05 18:14:06 -0400
committerAdam <Adam@anope.org>2010-06-18 20:58:54 -0400
commit031bc4a8b0dc456aca4d70dc260f626b64cd82b3 (patch)
tree74f9c217963e45f54c787ed83fc6d494232f5cd4
parent503958aa77382a85a041e195d04b7a2ec51589e3 (diff)
Merged branch threadingengine with master - Added a threading engine
-rw-r--r--CMakeLists.txt7
-rwxr-xr-xconfigure2
-rw-r--r--configure.in2
-rw-r--r--include/services.h1
-rw-r--r--include/threadengine.h116
-rw-r--r--src/CMakeLists.txt10
-rw-r--r--src/Makefile11
-rw-r--r--src/threadengine.cpp38
-rw-r--r--src/threadengine_pthread.cpp108
-rw-r--r--src/threadengine_win32.cpp104
10 files changed, 395 insertions, 4 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8493c5835..4ee4c13d5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -286,6 +286,13 @@ if(NOT MSVC)
if(HAVE_NSL_LIB)
set(LDFLAGS "${LDFLAGS} -lnsl")
endif(HAVE_NSL_LIB)
+ # Check if pthread_create is within the pthread library (if the library exists), and add it to the linker flags if needed
+ check_library_exists(pthread pthread_create "" HAVE_PTHREAD)
+ if(HAVE_PTHREAD)
+ set(LDFLAGS "${LDFLAGS} -pthread")
+ else(HAVE_PTHREAD)
+ message(FATAL_ERROR "The pthread library is required to build Anope")
+ endif(HAVE_PTHREAD)
endif(NOT WIN32)
endif(NOT MSVC)
diff --git a/configure b/configure
index da401733d..2d99c0b19 100755
--- a/configure
+++ b/configure
@@ -3398,6 +3398,8 @@ fi
+ANOPELIBS="$ANOPELIBS -pthread"
+
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
diff --git a/configure.in b/configure.in
index 4fb762d66..1bda1b300 100644
--- a/configure.in
+++ b/configure.in
@@ -95,6 +95,8 @@ int main()
AC_SUBST(ANOPELIBS)
AC_SUBST(LDFLAGS)
+ANOPELIBS="$ANOPELIBS -pthread"
+
AC_CHECK_HEADER(sys/types.h,AC_DEFINE(HAS_SYS_TYPES_H,1,"Has sys/types.h"))
dnl module checking based on Unreal's module checking code
AC_DEFUN(AC_ENABLE_DYN,
diff --git a/include/services.h b/include/services.h
index 4dd35a751..43e91a21b 100644
--- a/include/services.h
+++ b/include/services.h
@@ -358,6 +358,7 @@ typedef struct exception_ Exception;
typedef struct session_ Session;
#include "extensible.h"
+#include "threadengine.h"
#include "bots.h"
#include "opertype.h"
#include "modes.h"
diff --git a/include/threadengine.h b/include/threadengine.h
new file mode 100644
index 000000000..e2125c6bd
--- /dev/null
+++ b/include/threadengine.h
@@ -0,0 +1,116 @@
+#ifdef _WIN32
+typedef HANDLE ThreadHandle;
+typedef CRITICAL_SECTION MutexHandle;
+typedef HANDLE CondHandle;
+#else
+# include <pthread.h>
+typedef pthread_t ThreadHandle;
+typedef pthread_mutex_t MutexHandle;
+typedef pthread_cond_t CondHandle;
+#endif
+
+class ThreadEngine;
+class Thread;
+
+extern CoreExport ThreadEngine threadEngine;
+
+class ThreadEngine
+{
+ public:
+ /** Threadengines constructor
+ */
+ ThreadEngine();
+
+ /** Threadengines destructor
+ */
+ ~ThreadEngine();
+
+ /** Start a new thread
+ * @param thread A pointer to a newley allocated thread
+ */
+ void Start(Thread *thread);
+};
+
+class Thread : public Extensible
+{
+ private:
+ /* Set to true to tell the thread to finish and we are waiting for it */
+ bool Exit;
+
+ /** Join to the thread, sets the exit state to true
+ */
+ void Join();
+ public:
+ /* Handle for this thread */
+ ThreadHandle Handle;
+
+ /** Threads constructor
+ */
+ Thread();
+
+ /** Threads destructor
+ */
+ virtual ~Thread();
+
+ /** Sets the exit state as true informing the thread we want it to shut down
+ */
+ void SetExitState();
+
+ /** Returns the exit state of the thread
+ * @return true if we want to exit
+ */
+ bool GetExitState() const;
+
+ /** Called to run the thread, should be overloaded
+ */
+ virtual void Run();
+};
+
+class Mutex
+{
+ protected:
+ /* A mutex, used to keep threads in sync */
+ MutexHandle mutex;
+
+ public:
+ /** Constructor
+ */
+ Mutex();
+
+ /** Destructor
+ */
+ ~Mutex();
+
+ /** Attempt to lock the mutex, will hang until a lock can be achieved
+ */
+ void Lock();
+
+ /** Unlock the mutex, it must be locked first
+ */
+ void Unlock();
+};
+
+class Condition : public Mutex
+{
+ private:
+ /* A condition */
+ CondHandle cond;
+
+ public:
+ /** Constructor
+ */
+ Condition();
+
+ /** Destructor
+ */
+ ~Condition();
+
+ /** Called to wakeup the waiter
+ */
+ void Wakeup();
+
+ /** Called to wait for a Wakeup() call
+ */
+ void Wait();
+};
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4bad367b4..8cf232a77 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -2,14 +2,24 @@
file(GLOB SRC_SRCS_C RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.c")
file(GLOB SRC_SRCS_CPP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp")
set(SRC_SRCS ${SRC_SRCS_C} ${SRC_SRCS_CPP})
+
# Don't include win32_memory.cpp, it's only required by Visual Studio to override it's override of the new/delete operators
remove_item_from_list(SRC_SRCS win32_memory.cpp)
+
# If not using Windows, don't include windows.cpp, as it's Windows-specific
if(NOT WIN32)
remove_item_from_list(SRC_SRCS windows.cpp)
endif(NOT WIN32)
sort_list(SRC_SRCS)
+# If using Windows, remove the pthread threading engine from the list
+if(WIN32)
+ remove_item_from_list(SRC_SRCS threadengine_pthread.cpp)
+# If not using Windows, remove the Windows threading engine from the list
+else(WIN32)
+ remove_item_from_list(SRC_SRCS threadengine_win32.cpp)
+endif(WIN32)
+
# Set all the files to use C++ as well as set their compile flags (use the module-specific compile flags, though)
set_source_files_properties(${SRC_SRCS} PROPERTIES LANGUAGE CXX COMPILE_FLAGS "${CXXFLAGS}")
diff --git a/src/Makefile b/src/Makefile
index be4004ec9..3e66abc3d 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2,13 +2,14 @@ OBJS = actions.o base64.o bots.o botserv.o channels.o chanserv.o command.o comm
config.o configreader.o encrypt.o hashcomp.o hostserv.o init.o ircd.o language.o log.o mail.o main.o \
memory.o memoserv.o messages.o misc.o modes.o modules.o module.o modulemanager.o nickalias.o \
nickcore.o nickserv.o operserv.o process.o protocol.o regchannel.o send.o servers.o sessions.o slist.o \
- sockets.o timers.o opertype.o users.o wildcard.o
+ sockets.o threadengine.o threadengine_pthread.o timers.o opertype.o users.o wildcard.o
INCLUDES = ../include/commands.h ../include/defs.h ../include/language.h \
../include/pseudo.h ../include/sysconf.h ../include/config.h \
../include/messages.h ../include/services.h \
../include/timers.h ../include/extern.h \
- ../include/modules.h ../include/slist.h ../include/hashcomp.h
+ ../include/modules.h ../include/slist.h ../include/hashcomp.h \
+ ../include/threadengine.h
MAKEARGS = 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'ANOPELIBS=${ANOPELIBS}' \
'LDFLAGS=${LDFLAGS}' 'INSTDIR=${INSTDIR}' 'INSTALL=${INSTALL}' \
@@ -72,8 +73,10 @@ send.o: send.c $(INCLUDES)
servers.o: servers.cpp $(INCLUDES)
sessions.o: sessions.c $(INCLUDES)
slist.o: slist.c $(INCLUDES)
-sockets.o: sockets.cpp $(INCLUDES)
-timers.o: timers.cpp $(INCLUDES)
+sockets.o: sockets.cpp $(INCLUDES)
+threadengine.o: threadengine.cpp $(INCLUDES)
+threadengine_pthread.o: threadengine_pthread.cpp $(INCLUDES)
+timers.o: timers.cpp $(INCLUDES)
users.o: users.c $(INCLUDES)
wildcard.o: wildcard.cpp $(INCLUDES)
diff --git a/src/threadengine.cpp b/src/threadengine.cpp
new file mode 100644
index 000000000..f7e924fb6
--- /dev/null
+++ b/src/threadengine.cpp
@@ -0,0 +1,38 @@
+#include "services.h"
+
+ThreadEngine threadEngine;
+
+/** Threads constructor
+ */
+Thread::Thread() : Exit(false)
+{
+}
+
+/** Threads destructor
+ */
+Thread::~Thread()
+{
+ Join();
+}
+
+/** Sets the exit state as true informing the thread we want it to shut down
+ */
+void Thread::SetExitState()
+{
+ Exit = true;
+}
+
+/** Returns the exit state of the thread
+ * @return true if we want to exit
+ */
+bool Thread::GetExitState() const
+{
+ return Exit;
+}
+
+/** Called to run the thread, should be overloaded
+ */
+void Thread::Run()
+{
+}
+
diff --git a/src/threadengine_pthread.cpp b/src/threadengine_pthread.cpp
new file mode 100644
index 000000000..58b3a11ac
--- /dev/null
+++ b/src/threadengine_pthread.cpp
@@ -0,0 +1,108 @@
+#include "services.h"
+
+/** Join to the thread, sets the exit state to true
+ */
+void Thread::Join()
+{
+ SetExitState();
+ pthread_join(Handle, NULL);
+}
+
+/* Threadengine attributes used by this thread engine */
+static pthread_attr_t threadengine_attr;
+
+/** Entry point used for the threads
+ * @param parameter A Thread* cast to a void*
+ */
+static void *entry_point(void *parameter)
+{
+ Thread *thread = static_cast<Thread *>(parameter);
+ thread->Run();
+ return parameter;
+}
+
+/** Threadengines constructor
+ */
+ThreadEngine::ThreadEngine()
+{
+ if (pthread_attr_init(&threadengine_attr))
+ {
+ throw CoreException("ThreadEngine: Error calling pthread_attr_init");
+ }
+}
+
+/** Threadengines destructor
+ */
+ThreadEngine::~ThreadEngine()
+{
+ pthread_attr_destroy(&threadengine_attr);
+}
+
+/** Start a new thread
+ * @param thread A pointer to a newley allocated thread
+ */
+void ThreadEngine::Start(Thread *thread)
+{
+ if (pthread_create(&thread->Handle, &threadengine_attr, entry_point, thread))
+ {
+ delete thread;
+ throw CoreException("Unable to create thread");
+ }
+}
+
+/** Constructor
+ */
+Mutex::Mutex()
+{
+ pthread_mutex_init(&mutex, NULL);
+}
+
+/** Destructor
+ */
+Mutex::~Mutex()
+{
+ pthread_mutex_destroy(&mutex);
+}
+
+/** Attempt to lock the mutex, will hang until a lock can be achieved
+ */
+void Mutex::Lock()
+{
+ pthread_mutex_lock(&mutex);
+}
+
+/** Unlock the mutex, it must be locked first
+ */
+void Mutex::Unlock()
+{
+ pthread_mutex_unlock(&mutex);
+}
+
+/** Constructor
+ */
+Condition::Condition() : Mutex()
+{
+ pthread_cond_init(&cond, NULL);
+}
+
+/** Destructor
+ */
+Condition::~Condition()
+{
+ pthread_cond_destroy(&cond);
+}
+
+/** Called to wakeup the waiter
+ */
+void Condition::Wakeup()
+{
+ pthread_cond_signal(&cond);
+}
+
+/** Called to wait for a Wakeup() call
+ */
+void Condition::Wait()
+{
+ pthread_cond_wait(&cond, &mutex);
+}
+
diff --git a/src/threadengine_win32.cpp b/src/threadengine_win32.cpp
new file mode 100644
index 000000000..602d8b809
--- /dev/null
+++ b/src/threadengine_win32.cpp
@@ -0,0 +1,104 @@
+#include "services.h"
+
+/** Join to the thread, sets the exit state to true
+ */
+void Thread::Join()
+{
+ SetExitState();
+ WaitForSingleObject(Handle, INFINITE);
+}
+
+/** Entry point for the thread
+ * @param paramter A Thread* cast to a void*
+ */
+static DWORD WINAPI entry_point(void *parameter)
+{
+ Thread *thread = static_cast<Thread *>(parameter);
+ thread->Run();
+ return 0;
+}
+
+/** Threadengines constructor
+ */
+ThreadEngine::ThreadEngine()
+{
+}
+
+/** Threadengines destructor
+ */
+ThreadEngine::~ThreadEngine()
+{
+}
+
+/** Start a new thread
+ * @param thread A pointer to a newley allocated thread
+ */
+void ThreadEngine::Start(Thread *thread)
+{
+ thread->Handle = CreateThread(NULL, 0, entry_point, thread, 0, NULL);
+
+ if (!thread->Handle)
+ {
+ delete thread;
+ throw CoreException("Unable to create thread");
+ }
+}
+
+/** Constructor
+ */
+Mutex::Mutex()
+{
+ InitializeCriticalSection(&mutex);
+}
+
+/** Destructor
+ */
+Mutex::~Mutex()
+{
+ DeleteCriticalSection(&mutex);
+}
+
+/** Attempt to lock the mutex, will hang until a lock can be achieved
+ */
+void Mutex::Lock()
+{
+ EnterCriticalSection(&mutex);
+}
+
+/** Unlock the mutex, it must be locked first
+ */
+void Mutex::Unlock()
+{
+ LeaveCriticalSection(&mutex);
+}
+
+/** Constructor
+ */
+Condition::Condition() : Mutex()
+{
+ cond = CreateEvent(NULL, false, false, NULL);
+}
+
+/** Destructor
+ */
+Condition::~Condition()
+{
+ CloseHandle(cond);
+}
+
+/** Called to wakeup the waiter
+ */
+void Condition::Wakeup()
+{
+ PulseEvent(cond);
+}
+
+/** Called to wait for a Wakeup() call
+ */
+void Condition::Wait()
+{
+ LeaveCriticalSection(&mutex);
+ WaitForSingleObject(cond, INFINITE);
+ EnterCriticalSection(&mutex);
+}
+