Index: trunk/include/Socket.cpp
===================================================================
--- trunk/include/Socket.cpp	(revision f705d342f5e35285dedfdfc3d03a1c4fba683167)
+++ trunk/include/Socket.cpp	(revision ebcb766228104b857bc66c55a6c7f802fc9aab51)
@@ -31,7 +31,4 @@
 		core->listen(10);
 		core->ioctlsocket(FIONBIO, &NoBlock);
-
-		NSC_DEBUG_MSG_STD("Currently listeneing to: " + strEx::itos(core->port_));
-
 		while (!(WaitForSingleObject(hStopEvent, 100) == WAIT_OBJECT_0)) {
 			Socket client;
@@ -42,7 +39,8 @@
 		NSC_LOG_ERROR_STD(e.getMessage());
 	}
-
-	CloseHandle(hStopEvent);
-	NSC_DEBUG_MSG("Socket closed!");
+	HANDLE hTmp = hStopEvent;
+	hStopEvent = NULL;
+	BOOL b = CloseHandle(hTmp);
+	assert(b);
 	return 0;
 }
@@ -54,5 +52,5 @@
 */
 void simpleSocket::Listener::ListenerThread::exitThread(void) {
-	NSC_DEBUG_MSG("Requesting Socket shutdown!");
+	assert(hStopEvent);
 	if (!SetEvent(hStopEvent)) {
 		NSC_LOG_ERROR_STD("SetStopEvent failed");
@@ -85,5 +83,7 @@
 }
 void simpleSocket::Listener::close() {
-	threadManager_.exitThread();
+	if (threadManager_.hasActiveThread())
+		if (!threadManager_.exitThread())
+			throw new SocketException("Could not terminate thread.");
 	Socket::close();
 }
Index: trunk/include/Socket.h
===================================================================
--- trunk/include/Socket.h	(revision f705d342f5e35285dedfdfc3d03a1c4fba683167)
+++ trunk/include/Socket.h	(revision ebcb766228104b857bc66c55a6c7f802fc9aab51)
@@ -63,4 +63,5 @@
 		Socket(Socket &other) {
 			socket_ = other.socket_;
+			from_ = other.from_;
 			other.socket_ = NULL;
 		}
@@ -74,6 +75,6 @@
 		}
 		virtual void close() {
-			assert(socket_);
-			closesocket(socket_);
+			if (socket_)
+				closesocket(socket_);
 			socket_ = NULL;
 		}
@@ -115,4 +116,7 @@
 			if (::ioctlsocket(socket_, cmd, argp) == SOCKET_ERROR)
 				throw SocketException("ioctlsocket failed: ", ::WSAGetLastError());
+		}
+		std::string getAddrString() {
+			return inet_ntoa(from_.sin_addr);
 		}
 
Index: trunk/include/strEx.h
===================================================================
--- trunk/include/strEx.h	(revision f705d342f5e35285dedfdfc3d03a1c4fba683167)
+++ trunk/include/strEx.h	(revision ebcb766228104b857bc66c55a6c7f802fc9aab51)
@@ -62,4 +62,18 @@
 		return itos(i>>24)+"B";
 	}
+
+	typedef std::list<std::string> splitList;
+	inline splitList splitEx(std::string str, std::string key) {
+		splitList ret;
+		std::string::size_type pos = 0, lpos = 0;
+		while ((pos = str.find(key, pos)) !=  std::string::npos) {
+			ret.push_back(str.substr(lpos, pos-lpos));
+			lpos = ++pos;
+		}
+		if (lpos < str.size())
+			ret.push_back(str.substr(lpos));
+		return ret;
+	}
+
 	inline std::pair<std::string,std::string> split(std::string str, std::string key) {
 		std::string::size_type pos = str.find(key);
Index: trunk/include/thread.h
===================================================================
--- trunk/include/thread.h	(revision f7f536bf7d214df437f50e0f0d77f8ea4e72d875)
+++ trunk/include/thread.h	(revision ebcb766228104b857bc66c55a6c7f802fc9aab51)
@@ -1,63 +1,3 @@
-// Thread.h: interface for the Thread class.
-//
-//////////////////////////////////////////////////////////////////////
-
 #pragma once
-
-
-/**
- * @ingroup NSClientCompat
- * Simple unnamed mutex to handle thread exit wait (used by the Thread class below)
- *
- * @version 1.0
- * first version
- *
- * @date 02-13-2005
- *
- * @author mickem
- *
- * @par license
- * This code is absolutely free to use and modify. The code is provided "as is" with
- * no expressed or implied warranty. The author accepts no liability if it causes
- * any damage to your computer, causes your pet to fall ill, increases baldness
- * or makes your car start emitting strange noises when you start it up.
- * This code has no bugs, just undocumented features!
- * 
- */
-class UnnamedMutex {
-private:
-	HANDLE hMutex_;
-public:
-	/**
-	 * Default c-tor.
-	 * Creates an unnamed mutex with a given owner status
-	 * @param owner true if we want to become owner of the mutex
-	 */
-	UnnamedMutex(bool owner = false) {
-		hMutex_ = ::CreateMutex(NULL, owner, NULL);
-	}
-	/**
-	 * Default d-tor.
-	 * Closes the mutex
-	 */
-	virtual ~UnnamedMutex() {
-		CloseHandle(hMutex_);
-	}
-	/**
-	 * Wait for the mutex or timeout in dwMilliseconds milliseconds.
-	 * @param dwMilliseconds The timeout value
-	 * @return status
-	 */
-	DWORD wait(DWORD dwMilliseconds = 0L) {
-		return ::WaitForSingleObject(hMutex_, dwMilliseconds);
-	}
-	/**
-	 * Release the mutex
-	 * @return status
-	 */
-	BOOL free() {
-		return ::ReleaseMutex(hMutex_);
-	}
-};
 
 /**
@@ -89,11 +29,11 @@
 	HANDLE hThread_;		// Thread handle
 	DWORD dwThreadID_;		// Thread ID
-	UnnamedMutex endMutext;	// mutex to wait for end of thread
 	T* pObject_;			// Wrapped object
+	HANDLE hStopEvent_;		// Event to signal that the thread has stopped
 
 	typedef struct thread_param {
-		Thread* core;
-		T *instance;
-		LPVOID lpParam;
+		Thread* manager;	// The thread manager
+		T *instance;		// The thread instance object
+		LPVOID lpParam;		// The optional argument to the thread
 	} thread_param;
 
@@ -103,5 +43,5 @@
 	 * Sets up default values
 	 */
-	Thread() : endMutext(false), hThread_(NULL), dwThreadID_(0), pObject_(NULL) {}
+	Thread() : hThread_(NULL), dwThreadID_(0), pObject_(NULL), hStopEvent_(NULL) {}
 	/**
 	 * Default d-tor.
@@ -112,4 +52,6 @@
 		if (hThread_)
 			CloseHandle(hThread_);
+		if (hStopEvent_)
+			CloseHandle(hStopEvent_);
 	}
 
@@ -125,11 +67,13 @@
 		thread_param* param = static_cast<thread_param*>(lpParameter);
 		T* instance = param->instance;
-		Thread *core = param->core;
+		Thread *manager = param->manager;
 		LPVOID lpParam = param->lpParam;
 		delete param;
-		core->endMutext.wait();
+
+		assert(manager->hStopEvent_);
 		DWORD ret = instance->threadProc(lpParam);
-		core->endMutext.free();
-		return 0;
+		BOOL b = SetEvent(manager->hStopEvent_);
+		assert(b);
+		return ret;
 	}
 
@@ -142,17 +86,16 @@
 	 * @param lpParam An argument to the thread
 	 * @return An instance of the thread object.
-	 * @throws char
 	 * @bug the object return thing is *unsafe* and should be changed (if the thread is terminated that pointer is invalidated without any signal).
 	 */
-	T* createThread(LPVOID lpParam = NULL) {
-		if (pObject_)
-			throw "Could not create thread";
+	void createThread(LPVOID lpParam = NULL) {
+		assert(pObject_ == NULL);
+		assert(hStopEvent_ == NULL);
 		pObject_ = new T;
 		thread_param* param = new thread_param;
 		param->instance = pObject_;
-		param->core = this;
+		param->manager = this;
 		param->lpParam = lpParam;
+		hStopEvent_ = CreateEvent(NULL, TRUE, FALSE, NULL);
 		hThread_ = ::CreateThread(NULL,0,threadProc,reinterpret_cast<VOID*>(param),0,&dwThreadID_);
-		return pObject_;
 	}
 	/**
@@ -162,21 +105,27 @@
 	 */
 	bool exitThread(const unsigned int delay = 5000L) {
-		if (!pObject_)
-			throw "Could not terminate thread, has not been started yet...";
+		assert(pObject_ != NULL);
+		assert(hStopEvent_ != NULL);
 		pObject_->exitThread();
-		DWORD dwWaitResult = endMutext.wait(delay);
+
+		DWORD dwWaitResult = WaitForSingleObject(hStopEvent_, delay);
 		switch (dwWaitResult) {
 			// The thread got mutex ownership.
 			case WAIT_OBJECT_0:
-				// TODO: Potential race condition if multipåle threads try to terminate the thread...
-				delete pObject_;
-				pObject_ = NULL;
-				endMutext.free();
+				{
+					// @todo pObject should be protected!
+					HANDLE hTmp = hStopEvent_;
+					T* pTmp = pObject_;
+					pObject_ = NULL;
+					delete pTmp;
+					hStopEvent_ = NULL;
+					CloseHandle(hTmp);
+				}
 				return true;
-				// Cannot get mutex ownership due to time-out.
+				// Did not get a signal due to time-out.
 			case WAIT_TIMEOUT: 
 				return false; 
 
-				// Got ownership of the abandoned mutex object.
+				// Never got a signal.
 			case WAIT_ABANDONED: 
 				return false; 
@@ -184,4 +133,16 @@
 		return false;
 	}
+	bool hasActiveThread() const {
+		// @todo pObject should be protected!
+		return pObject_ != NULL;
+	}
+	const T* getThreadConst() const {
+		// @todo pObject should be protected!
+		return pObject_;
+	}
+	T* getThread() const {
+		// @todo pObject should be protected!
+		return pObject_;
+	}
 };
 
