]> gitweb.hamatoma.de Git - crepublib/commitdiff
ReThread, ReTCP for win32 net
authorHamatoma <git.tortouse@hm.f-r-e-i.de>
Thu, 12 Mar 2015 22:35:50 +0000 (23:35 +0100)
committerHamatoma <git.tortouse@hm.f-r-e-i.de>
Thu, 12 Mar 2015 22:39:59 +0000 (23:39 +0100)
base/ReLogger.hpp
base/ReThread.cpp [new file with mode: 0644]
base/ReThread.hpp [new file with mode: 0644]
base/baselocations.hpp
base/rebase.hpp
net/ReTCP.cpp
net/ReTCP.hpp
net/ReUdpConnection.hpp
net/renet.hpp

index 6ec0321af6c4c61ca44e6f2e8bbe8abac724cf35..f177aa4e712094b00fa60dfd64e3c92bdb591f6c 100644 (file)
@@ -180,7 +180,7 @@ protected:
        ReAppender* m_stdConsoleAppender;
        ReFileAppender* m_stdFileAppender;
        int m_locationOfOpenSayF;
-       sem_t m_mutex;
+       ReMutex_t m_mutex;
        char m_charPrefix;
 private:
 
diff --git a/base/ReThread.cpp b/base/ReThread.cpp
new file mode 100644 (file)
index 0000000..4c8959e
--- /dev/null
@@ -0,0 +1,104 @@
+/*\r
+ * ReThreadStarter.cpp\r
+ *\r
+ * License: Public domain\r
+ * Do what you want.\r
+ * No warranties and disclaimer of any damages.\r
+ * The latest sources: https://github.com/republib\r
+ */\r
+\r
+#include "base/rebase.hpp"\r
+\r
+enum RELOC_HASHLIST {\r
+       LC_SET_MASTER_LOGGER_1 = LC_THREAD + 1, // 50601\r
+       LC_START_THREAD_1,              // 50602\r
+};\r
+\r
+/**\r
+ * Constructor.\r
+ */\r
+ReThread::ReThread() :\r
+       m_logger(false),\r
+       m_appender(NULL){\r
+}\r
+/**\r
+ * Destructor.\r
+ */\r
+ReThread::~ReThread(){\r
+}\r
+\r
+void ReThread::setMasterLogger(ReLogger* masterLogger){\r
+       if (m_appender == NULL){\r
+               m_appender = new ReSlaveAppender(masterLogger);\r
+       } else {\r
+               globalLogger()->say(LOG_ERROR | CAT_LIB, LC_NEXT_1,\r
+                   i18n("setMasterLogger() is called multiple times"));\r
+       }\r
+}\r
+\r
+/**\r
+ * Constructor.\r
+ */\r
+ReThreadStarter::ReThreadStarter(ReLogger* logger) :\r
+       m_id(0),\r
+       m_logger(logger){\r
+}\r
+/**\r
+ * Destructor.\r
+ */\r
+ReThreadStarter::~ReThreadStarter(){\r
+}\r
+\r
+#if defined __linux__\r
+/**\r
+ * The start routine of pthread_start\r
+ *\r
+ * This will handle the connection for each client (in an own thread).\r
+ *\r
+ * @param pConnection  a void* pointer to the <code>ReThread</code> instance\r
+ * */\r
+static void* starterFunction(void *pConnection) {\r
+       ReThread* thread = reinterpret_cast<ReThread*>(pConnection);\r
+       thread->run();\r
+}\r
+#elif defined __WIN32__\r
+DWORD WINAPI starterFunction(_In_  LPVOID pParameter){\r
+       ReThread* thread = reinterpret_cast<ReThread*>(pConnection);\r
+       thread->run();\r
+       return 0;\r
+}\r
+\r
+#endif\r
+/**\r
+ * Starts a new thread.\r
+ *\r
+ * @param thread       the\r
+ */\r
+void ReThreadStarter::startThread(ReThread& thread){\r
+       thread.setId(++m_nextId);\r
+       thread.setMasterLogger(m_logger);\r
+       bool error;\r
+#if defined __linux__\r
+       pthread_t sniffer_thread;\r
+       error = (pthread_create(&sniffer_thread, NULL, starterFunction,\r
+           (void*) thread) < 0;\r
+\r
+#else defined __WIN32__\r
+       HANDLE threadHandle;\r
+       error = (threadHandle = CreateThread(NULL, 0, starterFunction,\r
+               &thread, 0)) == NULL;\r
+                 _In_opt_   LPSECURITY_ATTRIBUTES lpThreadAttributes,\r
+                 _In_       SIZE_T dwStackSize,\r
+                 _In_       LPTHREAD_START_ROUTINE lpStartAddress,\r
+                 _In_opt_   LPVOID lpParameter,\r
+                 _In_       DWORD dwCreationFlags,\r
+                 _Out_opt_  LPDWORD lpThreadId\r
+               );\r
+#endif\r
+       if (error)\r
+               m_logger->sayF(LOG_ERROR | CAT_PROCESS,\r
+                       LC_START_THREAD_1,\r
+                       i18n("cannot create a thread: $1")).arg(\r
+                       getLastOSError()).end();\r
+\r
+}\r
diff --git a/base/ReThread.hpp b/base/ReThread.hpp
new file mode 100644 (file)
index 0000000..f6b088d
--- /dev/null
@@ -0,0 +1,47 @@
+/*\r
+ * ReThreadStarter.hpp\r
+ *\r
+ * License: Public domain\r
+ * Do what you want.\r
+ * No warranties and disclaimer of any damages.\r
+ * The latest sources: https://github.com/republib\r
+ */\r
+\r
+#ifndef BASE_RETHREAD_HPP_\r
+#define BASE_RETHREAD_HPP_\r
+\r
+/**\r
+ * Abstract base class for threads\r
+ *\r
+ * Starting is done with a <code>ReThreadStarter</code>.\r
+ */\r
+class ReThread {\r
+public:\r
+       ReThread();\r
+       virtual ~ReThread();\r
+private:\r
+       friend class ReThreadStarter;\r
+       void setId(int id);\r
+       void setMasterLogger(ReLogger* masterLogger);\r
+public:\r
+       virtual void run() = 0;\r
+protected:\r
+       int m_id;\r
+       ReLogger m_logger;\r
+       ReSlaveAppender* m_appender;\r
+};\r
+\r
+/**\r
+ * Offers a portable way to start threads.\r
+ */\r
+class ReThreadStarter {\r
+public:\r
+       ReThreadStarter(ReLogger* logger);\r
+       virtual ~ReThreadStarter();\r
+public:\r
+       void startThread(ReThread& thread);\r
+private:\r
+       int m_nextId;\r
+       ReLogger* m_logger;\r
+};\r
+#endif /* BASE_RETHREAD_HPP_ */\r
index be561340c9f272bcd29c85e7ef50ffaac8466422..7ef4b400ce4e9c4dacffcf55e1711de7746741b2 100644 (file)
@@ -19,6 +19,7 @@ enum RELOC_LIB {
        LC_HASHLIST = 50300,
        LC_TRAVERSER = 50400,
        LC_TCP = 50500,
+       LC_THREAD = 50600,
 };
 enum RELOC_UDPCONNECTION {
        LC_UDPCONNECTION_CONSTRUCT = 50101,
index 9f0e26ebe2a60dfa82d68132f24bb811dfbffc35..93b40f0b92fbd36696b5bb2a71e8121530dbb3dd 100644 (file)
-/*
- * rebase.hpp
- *
- * License: Public domain
- * Do what you want.
- * No warranties and disclaimer of any damages.
- * The latest sources: https://github.com/republib
- */
-#ifndef REBASE_HPP_
-#define REBASE_HPP_
-#include <stdlib.h>
-#include <string.h>
-#include <malloc.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <errno.h>
-#include <ctype.h>
-#include <assert.h>
-#include <stdarg.h>
-#include <limits.h>
-#include <pthread.h>
-#include <semaphore.h>
-
-#define __LITTLE_ENDIAN__
-//#define __BIG_ENDIAN__
-
-#if defined __linux__
-
-#      include <sys/time.h>
-#      include <stddef.h>
-#      include <dirent.h>
-#      include <fnmatch.h>
-#      include <regex.h>
-#      include <unistd.h>
-#      include <inttypes.h>
-#      include <fcntl.h>
-typedef u_int64_t uint64_t;
-typedef u_int8_t uint8_t;
-typedef __off_t ReFileSize_t;
-typedef timespec ReFileTime_t;
-#      define _strdup strdup
-#      define _unlink unlink
-#      define _strnicmp(s1, s2, n) strncasecmp(s1, s2, n)
-#      define _stricmp(s1, s2) strcasecmp(s1, s2)
-#      define _snprintf snprintf
-#      define _memcmp(t,s,n) memcmp(t,s,n)
-#      define _mkdir(path, mode) mkdir(path, mode)
-#      define _rmdir(path) rmdir(path)
-#      define OS_SEPARATOR_CHAR '/'
-#      define OS_SEPARATOR "/"
-inline int getLastOSError() {
-       return errno;
-}
-#elif defined __WIN32__
-#      include <direct.h>
-#      include <windows.h>
-#      define _memcmp(t,s,n) memcmp(t,s,n)
-#      define lstat stat
-#      define OS_SEPARATOR_CHAR '\\'
-#      define OS_SEPARATOR "\\"
-typedef _int64 int64_t;
-typedef unsigned long long uint64_t;
-typedef unsigned char uint8_t;
-typedef unsigned long uint32_t;
-typedef long int int32_t;
-typedef int64_t ReFileSize_t;
-typedef FILETIME ReFileTime_t;
-#      define S_ISDIR(mode) (((mode) & _S_IFDIR) != 0)
-#      define ALLPERMS 0
-//#    define _mkdir(name, mode) (!CreateDirectory(name, NULL))
-#      define _mkdir(name, mode) _mkdir(name)
-inline int getLastOSError() {
-       return GetLastError();
-}
-#endif
-
-#define RE_TESTUNIT
-#include "base/ReByteBuffer.hpp"
-#include "base/ReVarArgs.hpp"
-#include "base/ReLogger.hpp"
-#include "base/ReTestUnit.hpp"
-#include "base/ReCString.hpp"
-#include "base/ReException.hpp"
-#include "base/ReStringUtils.hpp"
-#include "base/ReDirectory.hpp"
-#include "base/ReSeqArray.hpp"
-#include "base/ReStringList.hpp"
-#include "base/ReHashList.hpp"
-#include "base/ReConfigFile.hpp"
-#include "base/ReI18N.hpp"
-#include "base/ReProgramArgs.hpp"
-#include "base/ReAppenders.hpp"
-
-typedef unsigned char byte_t;
-typedef int ReErrNo_t;
-#include "../base/baselocations.hpp"
-#endif /* REBASE_HPP_ */
+/*\r
+ * rebase.hpp\r
+ *\r
+ * License: Public domain\r
+ * Do what you want.\r
+ * No warranties and disclaimer of any damages.\r
+ * The latest sources: https://github.com/republib\r
+ */\r
+#ifndef REBASE_HPP_\r
+#define REBASE_HPP_\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <malloc.h>\r
+#include <stdio.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#include <time.h>\r
+#include <errno.h>\r
+#include <ctype.h>\r
+#include <assert.h>\r
+#include <stdarg.h>\r
+#include <limits.h>\r
+\r
+#define __LITTLE_ENDIAN__\r
+//#define __BIG_ENDIAN__\r
+\r
+#if defined __linux__\r
+\r
+#      include <sys/time.h>\r
+#      include <stddef.h>\r
+#      include <dirent.h>\r
+#      include <fnmatch.h>\r
+#      include <regex.h>\r
+#      include <unistd.h>\r
+#      include <inttypes.h>\r
+#      include <fcntl.h>\r
+#include <pthread.h>\r
+#include <semaphore.h>\r
+typedef u_int64_t uint64_t;\r
+typedef u_int8_t uint8_t;\r
+typedef __off_t ReFileSize_t;\r
+typedef timespec ReFileTime_t;\r
+typedef sem_t ReMutex_t;\r
+#define reInitMutex(mutex)\r
+#      define _strdup strdup\r
+#      define _unlink unlink\r
+#      define _strnicmp(s1, s2, n) strncasecmp(s1, s2, n)\r
+#      define _stricmp(s1, s2) strcasecmp(s1, s2)\r
+#      define _snprintf snprintf\r
+#      define _memcmp(t,s,n) memcmp(t,s,n)\r
+#      define _mkdir(path, mode) mkdir(path, mode)\r
+#      define _rmdir(path) rmdir(path)\r
+#      define OS_SEPARATOR_CHAR '/'\r
+#      define OS_SEPARATOR "/"\r
+inline int getLastOSError() {\r
+       return errno;\r
+}\r
+#elif defined __WIN32__\r
+#      include <direct.h>\r
+#      include <WinSock2.h>\r
+#      include <windows.h>\r
+#      define _memcmp(t,s,n) memcmp(t,s,n)\r
+#      define lstat stat\r
+#      define OS_SEPARATOR_CHAR '\\'\r
+#      define OS_SEPARATOR "\\"\r
+typedef HANDLE ReMutex_t;\r
+#define initMutex(mutex) mutex = CreateMutex(NULL, FALSE, NULL) \r
+typedef _int64 int64_t;\r
+typedef unsigned long long uint64_t;\r
+typedef unsigned char uint8_t;\r
+typedef unsigned long uint32_t;\r
+typedef long int int32_t;\r
+typedef int64_t ReFileSize_t;\r
+typedef FILETIME ReFileTime_t;\r
+#      define S_ISDIR(mode) (((mode) & _S_IFDIR) != 0)\r
+#      define ALLPERMS 0\r
+//#    define _mkdir(name, mode) (!CreateDirectory(name, NULL))\r
+#      define _mkdir(name, mode) _mkdir(name)\r
+inline int getLastOSError() {\r
+       return GetLastError();\r
+}\r
+#endif\r
+\r
+#define RE_TESTUNIT\r
+#include "base/ReByteBuffer.hpp"\r
+#include "base/ReVarArgs.hpp"\r
+#include "base/ReLogger.hpp"\r
+#include "base/ReTestUnit.hpp"\r
+#include "base/ReCString.hpp"\r
+#include "base/ReException.hpp"\r
+#include "base/ReStringUtils.hpp"\r
+#include "base/ReDirectory.hpp"\r
+#include "base/ReSeqArray.hpp"\r
+#include "base/ReStringList.hpp"\r
+#include "base/ReHashList.hpp"\r
+#include "base/ReConfigFile.hpp"\r
+#include "base/ReI18N.hpp"\r
+#include "base/ReProgramArgs.hpp"\r
+#include "base/ReAppenders.hpp"\r
+\r
+typedef unsigned char byte_t;\r
+typedef int ReErrNo_t;\r
+#include "../base/baselocations.hpp"\r
+#endif /* REBASE_HPP_ */\r
index 8995ef9bb2d5d8db315ca80abc17f55a21e07252..7a77901778dad8f813faf82dfa0d88012e14b961 100644 (file)
@@ -26,7 +26,13 @@ enum LOCATION_DIRTOOL {
        LC_RECEIVE_4,                   // 50515
        LC_CONNECT_2,                   // 50516
        LC_CONNECT_3,                   // 50517
+       LC_TCP_CONNECTION_1,    // 50518
 };
+
+#if defined __WIN32__
+bool ReTCPConnection::isGlobalInitialized = false;
+#endif
+
 /**
  * Constructor.
  *
@@ -123,7 +129,6 @@ bool ReTCPClient::connect(const char* ip, int port) {
        bool rc = false;
        struct addrinfo hints;
        struct addrinfo* addr = NULL;
-       int sockfd;
 
        memset(&hints, 0, sizeof hints);
        hints.ai_family = AF_UNSPEC;
@@ -167,6 +172,15 @@ ReTCPConnection::ReTCPConnection(int id, ReLogger* logger) :
            m_id(id),
            m_noSent(0),
            m_noReceived(0) {
+#if defined __WIN32__
+       WSADATA wsaData;
+       if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0){\r
+        m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_TCP_CONNECTION_1,
+                   i18n("WSAStartup() failed: $1")).arg(errno).arg(getLastOSError()).end();\r
+               throw ReException("WSAStartup() failed");\r
+    }\r
+
+#endif
 }
 
 /**
@@ -179,11 +193,20 @@ ReTCPConnection::~ReTCPConnection() {
  */
 void ReTCPConnection::close() {
        if (m_handleSocket >= 0) {
-               ::close(m_handleSocket);
+               reCloseSocket(m_handleSocket);
                m_handleSocket = -1;
        }
 }
 
+/**
+ * Frees the global resources.
+ */
+void ReTCPConnection::globalClose(){
+#if defined __WIN32__
+       WSACleanup();
+#endif
+}
+
 /**
  * Sets the address given by a family and a string like "192.168.0.1:22".
  *
@@ -312,8 +335,6 @@ ReTCPServerConnection::~ReTCPServerConnection() {
  * Serves the commands of a single connection (in a single thread).
  */
 void ReTCPServerConnection::handleConnection() {
-//Get the socket descriptor
-       int read_size;
        ReByteBuffer command;
        ReNetCommandHandler::ProcessingState rc = ReNetCommandHandler::PS_UNDEF;
        do {
@@ -438,7 +459,8 @@ bool ReTCPServer::listenForAll() {
                int yes = 1;
                // Avoid the "Address already in use" error message of finished processes
                // that are still waiting for the release by the kernel:
-               if (setsockopt(m_handleSocket, SOL_SOCKET, SO_REUSEADDR, &yes,
+               if (setsockopt(m_handleSocket, SOL_SOCKET, SO_REUSEADDR, 
+                       reinterpret_cast<const char*>(&yes),
                    sizeof(int)) == -1) {
                        m_logger->sayF(LOG_WARNING | CAT_NETWORK, LC_LISTEN_FOR_ALL_7,
                            i18n("setsockopt() failed: $1")).arg(errno).end();
@@ -471,7 +493,7 @@ bool ReTCPServer::listenForAll() {
                                            LC_LISTEN_FOR_ALL_5,
                                            i18n("connection refused (too many connections): $1"))
                                            .arg(m_port).end();
-                                       ::close(clientSocket);
+                                       reCloseSocket(clientSocket);
                                } else {
                                        pthread_t sniffer_thread;
                                        ReTCPConnection* connection = createConnection(nextId++,
@@ -483,7 +505,7 @@ bool ReTCPServer::listenForAll() {
                                                    LC_LISTEN_FOR_ALL_6,
                                                    i18n("cannot create a thread: $1")).arg(
                                                    getLastOSError()).end();
-                                               ::close(clientSocket);
+                                               reCloseSocket(clientSocket);
                                                clientSocket = -1;
                                        }
 
index a13fa6e437fc8e063e49c094b9109c94516396a2..4364ed8365bcbeae448f899806097fa8a5cfa66c 100644 (file)
@@ -9,6 +9,12 @@
 
 #ifndef NET_RETCP_HPP_
 #define NET_RETCP_HPP_
+
+#if defined __linux__
+#      define reCloseSocket(handle)    ::close(handle)
+#elif defined __WIN32__
+#      define reCloseSocket(handle)    ::closesocket(handle)
+#endif
 /**
  * Administrates the internal data of an ip address, usable for IP4 and IP6.
  */
@@ -97,8 +103,13 @@ protected:
        int m_id;
        uint32_t m_noSent;
        uint32_t m_noReceived;
+#if defined __WIN32__
+private:
+       static bool isGlobalInitialized;
+#endif
+public:
+       static void globalClose();
 };
-
 /**
  * Implements a TCP client.
  */
index 48ffd4911b5a3a25e612302b765749dfd15990c6..36ae8a2df94076fa0dac4a4c26a0df19ae6d12d8 100644 (file)
@@ -8,12 +8,6 @@
 #ifndef UDPSERVER_H_
 #define UDPSERVER_H_
 
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-
 /**
  * Implements a base class for UDP server and client.
  */
index 840ff532dfd1bea91a8cd20fc969b2c114c1da0b..0ccc8c04ef4bb1319d5fddee40aebf9b0f6e7b2a 100644 (file)
@@ -1,20 +1,24 @@
-/*
- * renet.hpp
- *
- * License: Public domain
- * Do what you want.
- * No warranties and disclaimer of any damages.
- * The latest sources: https://github.com/republib
- *
- */
-
-#ifndef NET_RENET_HPP_
-#define NET_RENET_HPP_
-
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include "net/ReUdpConnection.hpp"
-#include "net/ReTCP.hpp"
-#endif /* NET_RENET_HPP_ */
+/*\r
+ * renet.hpp\r
+ *\r
+ * License: Public domain\r
+ * Do what you want.\r
+ * No warranties and disclaimer of any damages.\r
+ * The latest sources: https://github.com/republib\r
+ *\r
+ */\r
+\r
+#ifndef NET_RENET_HPP_\r
+#define NET_RENET_HPP_\r
+\r
+#if defined __linux__\r
+#include <arpa/inet.h>\r
+#include <netinet/in.h>\r
+#include <sys/socket.h>\r
+#include <netdb.h>\r
+#elif defined __WIN32__\r
+#include <ws2tcpip.h>\r
+#endif\r
+#include "net/ReUdpConnection.hpp"\r
+#include "net/ReTCP.hpp"\r
+#endif /* NET_RENET_HPP_ */\r