From 60840e78e0a2e25a0897bf9112e5d66957d7ff78 Mon Sep 17 00:00:00 2001 From: Hamatoma Date: Wed, 18 Mar 2015 10:28:15 +0100 Subject: [PATCH] Win32 corrections --- base/ReByteBuffer.cpp | 4 ++-- base/ReLogger.cpp | 2 ++ base/ReMutex.cpp | 19 ++++++++++++++----- base/ReMutex.hpp | 8 ++++---- base/ReThread.cpp | 20 ++++++++++---------- base/ReThread.hpp | 2 +- base/rebase.hpp | 6 ++++++ cunit/cuReTCP.cpp | 8 ++++---- net/ReTCP.cpp | 15 +++++++++++++-- os/ReDirTools.cpp | 4 +++- 10 files changed, 59 insertions(+), 29 deletions(-) diff --git a/base/ReByteBuffer.cpp b/base/ReByteBuffer.cpp index 431e324..9d19ff3 100644 --- a/base/ReByteBuffer.cpp +++ b/base/ReByteBuffer.cpp @@ -220,12 +220,12 @@ ReByteBuffer& ReByteBuffer::appendDump(const char* data, size_t length, int maxL if (length == size_t(-1)){ length = strlen(data); } - if (length > maxLength) + if ((int) length > maxLength) length = maxLength; // test if text or binary: bool isBinary = false; unsigned char cc; - for (int ii = 0; ii < length; ii++){ + for (size_t ii = 0; ii < length; ii++){ if ( (cc = (unsigned char) data[ii]) > 126 || (cc < ' ' && cc != '\n' && cc != '\r' && cc != '\t')){ isBinary = true; diff --git a/base/ReLogger.cpp b/base/ReLogger.cpp index d2acda4..2471b56 100644 --- a/base/ReLogger.cpp +++ b/base/ReLogger.cpp @@ -466,11 +466,13 @@ const char* ReLogger::standardPrefix(char charPrefix) { * */ void ReLogger::end(void) { + m_mutex.lock(); for (size_t ii = 0; ii < m_appenderListLength; ii++) { ReAppender* app = m_appenderList[ii]; if (app->accept(m_mode)) app->say(this, NULL); } + m_mutex.unlock(); m_locationOfOpenSayF = 0; } diff --git a/base/ReMutex.cpp b/base/ReMutex.cpp index dae5259..e6427b2 100644 --- a/base/ReMutex.cpp +++ b/base/ReMutex.cpp @@ -13,18 +13,22 @@ * Constructor. * * @param maxWaitSec maximal timeout. If reached an error occurres + * @param assignments time units for busy wait before waiting. Only used in WIN32
+ * use it for very short critical sections like variable assignment + * 0: wait at once
+ * otherwise: wait spinCount time (3 instructions) units before wait */ -ReMutex::ReMutex(int location, int maxWaitSec) : +ReMutex::ReMutex(int location, int maxWaitSec, int assignments) : #if defined __linux__ m_mutex(), #elif defined __WIN32__ - m_mutex(0), + m_mutex(), #endif m_maxWaitSec(maxWaitSec) { #if defined __linux__ sem_init(&m_mutex, 0, 1); #elif defined __WIN32__ - m_mutex = CreateMutex(NULL, FALSE, NULL); + InitializeCriticalSectionAndSpinCount(&m_mutex, min (assignments, 8) * 0x100); #endif } @@ -35,7 +39,7 @@ ReMutex::~ReMutex() { #if defined __linux__ sem_destroy(&m_mutex); #elif defined __WIN32__ - CloseMutex(m_mutex); + DeleteCriticalSection(&m_mutex); #endif } @@ -47,7 +51,12 @@ bool ReMutex::timedLock(int sec) { time.tv_nsec = 0; rc = sem_timedwait(&m_mutex, &time) == 0; #elif defined __WIN32__ - + int maxCount = sec * 50; + int count = 0; + while(TryEnterCriticalSection(&m_mutex) != 0 && ++count < maxCount){ + Sleep(20); + } + rc = count < maxCount; #endif return rc; } diff --git a/base/ReMutex.hpp b/base/ReMutex.hpp index 138a05b..04310b6 100644 --- a/base/ReMutex.hpp +++ b/base/ReMutex.hpp @@ -12,7 +12,7 @@ class ReMutex { public: - ReMutex(int location, int maxWaitSec = -1); + ReMutex(int location, int maxWaitSec = -1, int spinCount = 0); virtual ~ReMutex(); public: bool timedLock(int sec = -1); @@ -20,21 +20,21 @@ public: #if defined __linux__ sem_wait(&m_mutex); #elif defined __WIN32__ -#error "mutex in ReMutex missed" + EnterCriticalSection(&m_mutex); #endif } inline void unlock() { #if defined __linux__ sem_post(&m_mutex); #elif defined __WIN32__ -#error "mutex in ReMutex missed" + LeaveCriticalSection(&m_mutex); #endif } private: #if defined __linux__ sem_t m_mutex; #elif defined __WIN32__ - HANDLE m_mutex; + CRITICAL_SECTION m_mutex; #endif int m_maxWaitSec; }; diff --git a/base/ReThread.cpp b/base/ReThread.cpp index 7a06693..95706a9 100644 --- a/base/ReThread.cpp +++ b/base/ReThread.cpp @@ -32,7 +32,8 @@ ReThread::ReThread(bool autoDelete) : #if defined __linux__ m_threadInfo(), #elif defined __WIN32__ - m_threadInfo(UNDEF_HANDLE), + m_threadInfo(NULL), + m_osThreadId(0), #endif m_shouldStop(false), m_isStopped(false), @@ -69,7 +70,7 @@ void ReThread::kill() { #if defined __linux__ pthread_kill(m_threadInfo, SIGKILL); #elif defined __WIN32__ - KillThread(m_threadInfo); + TerminateThread(m_threadInfo, 254); #endif } /** @@ -110,7 +111,7 @@ void ReThread::runAndFinish() { #if defined __linux__ pthread_exit(NULL); #elif defined __WIN32__ - StopThread(m_threadInfo); + // Nothing to do #endif m_isStopped = true; } @@ -220,7 +221,7 @@ void ReThreadPool::killAllThreads() { } m_mutexThreads.unlock(); if (countWaiting > 0) - sleep(1); + millisecSleep(1000); } // now we kill: countWaiting = 0; @@ -240,7 +241,7 @@ void ReThreadPool::killAllThreads() { } if (countWaiting > 0) // wait 1 msec for end of kill: - usleep(1000); + millisecSleep(1); // we destroy all threads marked with auto delete: m_mutexThreads.lock(); for (int ii = 0; ii < m_maxThreads; ii++) { @@ -282,7 +283,7 @@ void* globalThreadStarterFunction(void *pConnection) { return NULL; } #elif defined __WIN32__ -DWORD WINAPI globalThreadStarterFunction(_In_ LPVOID pParameter) { +DWORD WINAPI globalThreadStarterFunction(_In_ LPVOID pConnection) { ReThread* thread = reinterpret_cast(pConnection); thread->runAndFinish(); return 0; @@ -310,9 +311,8 @@ bool ReThreadPool::startThread(ReThread* thread) { globalThreadStarterFunction, reinterpret_cast(thread)) >= 0; #elif defined __WIN32__ - HANDLE threadHandle; - ok = (threadHandle = CreateThread(NULL, 0, globalThreadStarterFunction, - &thread, 0)) != NULL; + ok = (thread->m_threadInfo = CreateThread(NULL, 0, globalThreadStarterFunction, + reinterpret_cast(thread), 0, &thread->m_osThreadId)) != NULL; #endif if (!ok) m_logger->sayF(LOG_ERROR | CAT_PROCESS, LC_START_THREAD_1, @@ -350,7 +350,7 @@ bool ReThreadPool::waitForAlmostAll(int mayResist, int timeoutSec) { rc = true; break; } - usleep(200 * 1000); + millisecSleep(200); now = time(NULL); } while (now < start + timeoutSec); return rc; diff --git a/base/ReThread.hpp b/base/ReThread.hpp index e9ea973..0d970e7 100644 --- a/base/ReThread.hpp +++ b/base/ReThread.hpp @@ -39,7 +39,6 @@ public: inline void setShouldStop(bool value) { m_shouldStop = value; } -private: private: friend class ReThreadPool; void kill(); @@ -59,6 +58,7 @@ protected: pthread_t m_threadInfo; #elif defined __WIN32__ HANDLE m_threadInfo; + DWORD m_osThreadId; #endif bool m_shouldStop; bool m_isStopped; diff --git a/base/rebase.hpp b/base/rebase.hpp index 965a99e..6a109f0 100644 --- a/base/rebase.hpp +++ b/base/rebase.hpp @@ -7,6 +7,8 @@ * The latest sources: https://github.com/republib */ #ifndef REBASE_HPP_ +#define min() +#define max() #define REBASE_HPP_ #include #include @@ -51,6 +53,7 @@ typedef timespec ReFileTime_t; # define _rmdir(path) rmdir(path) # define OS_SEPARATOR_CHAR '/' # define OS_SEPARATOR "/" +# define millisecSleep(msec) usleep(msec*1000) inline int getLastOSError() { return errno; } @@ -58,8 +61,11 @@ inline int getLastOSError() { # include # include # include +#undef min +#undef max # define _memcmp(t,s,n) memcmp(t,s,n) # define lstat stat +# define millisecSleep(msec) Sleep(msec) # define OS_SEPARATOR_CHAR '\\' # define OS_SEPARATOR "\\" typedef _int64 int64_t; diff --git a/cunit/cuReTCP.cpp b/cunit/cuReTCP.cpp index 472e7b2..e3960d4 100644 --- a/cunit/cuReTCP.cpp +++ b/cunit/cuReTCP.cpp @@ -13,7 +13,7 @@ static int s_port = 58111; class TCPThread: public ReThread { public: TCPThread(const char* task) : - ReThread(999), + ReThread(true), m_task(task) { } public: @@ -77,14 +77,14 @@ public: client.receive(command, answer); } int64_t duration = ReBaseUtils::milliSecSince(start); - int duration2 = time(NULL) - start2; + int duration2 = int(time(NULL) - start2); if (duration2 == 0) duration2 = 1; char msg[256]; int miByte = count * (size / (1024 * 1024)); - snprintf(msg, sizeof msg, + _snprintf(msg, sizeof msg, "%s: %d MiByte in %s/%d sec: %.3f (%.3f) MiByte/sec", direction, - miByte, ReByteBuffer("").appendMilliSec(duration).str(), + miByte, ReByteBuffer("").appendMilliSec((int) duration).str(), duration2, miByte * 1000.0 / (double) duration, miByte / (double) duration2); logger->say(LOG_INFO | CAT_LIB, location, msg); diff --git a/net/ReTCP.cpp b/net/ReTCP.cpp index 313341d..a1a2cf0 100644 --- a/net/ReTCP.cpp +++ b/net/ReTCP.cpp @@ -114,9 +114,12 @@ void ReSocketAddress::setAddress(const char* ip, int port) { * * @param logger logger for the error handling */ +#pragma warning( push ) +#pragma warning( disable : 4355 ) ReTCPClient::ReTCPClient(ReLogger* logger) : ReTCPConnection(-1, this), m_logger(logger) { +#pragma warning( pop ) } /** * Destructor. @@ -187,11 +190,10 @@ ReTCPConnection::ReTCPConnection(int id, ReLoggerOwner* loggerOwner) : #if defined __WIN32__ WSADATA wsaData; if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { - m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_TCP_CONNECTION_1, + loggerOwner->logger()->sayF(LOG_ERROR | CAT_NETWORK, LC_TCP_CONNECTION_1, i18n("WSAStartup() failed: $1")).arg(errno).arg(getLastOSError()).end(); throw ReException("WSAStartup() failed"); } - #endif } @@ -347,10 +349,13 @@ void ReTCPConnection::send(const char* command, const char* data, int length) { * @param id an identifier for logging * @param logger the logger for error handling */ +#pragma warning( push ) +#pragma warning( disable : 4355 ) ReTCPServerConnection::ReTCPServerConnection(int id, ReTCPServer* server) : ReTCPConnection(id, this), ReThread(true), m_server(server) { +#pragma warning( pop ) } /** @@ -389,6 +394,8 @@ void ReTCPServerConnection::run() { * @param logger the logger for error handling * @param maxConnections maximal count of threads handling a connection */ +#pragma warning( push ) +#pragma warning( disable : 4355 ) ReTCPServer::ReTCPServer(int port, class ReNetCommandHandler& commandHandler, ReLogger* logger, int maxConnections) : ReTCPConnection(0, this), @@ -397,6 +404,7 @@ ReTCPServer::ReTCPServer(int port, class ReNetCommandHandler& commandHandler, m_connections(new ReTCPServerConnection*[maxConnections]), m_handler(commandHandler), m_logger(logger) { +#pragma warning( pop ) m_port = port; memset(m_connections, 0, maxConnections * sizeof *m_connections); } @@ -569,9 +577,12 @@ void ReNetCommandHandler::addHandler(ReNetCommandHandler* handler) { * @param port port for listening * @param logger logger for error handling */ +#pragma warning( push ) +#pragma warning( disable : 4355 ) ReTCPEchoServer::ReTCPEchoServer(int port, ReLogger* logger) : ReTCPServer(port, *this, logger), ReNetCommandHandler() { +#pragma warning( pop ) } /** * Destructor. diff --git a/os/ReDirTools.cpp b/os/ReDirTools.cpp index d9f95ca..eb5b261 100644 --- a/os/ReDirTools.cpp +++ b/os/ReDirTools.cpp @@ -687,6 +687,8 @@ void ReDirOptions::setFilterFromProgramArgs(ReDirEntryFilter_t& filter) { * directory will be added as argument * @param logger logger for error messages */ +#pragma warning( push ) +#pragma warning( disable : 4355 ) ReTool::ReTool(const char* usage[], const char* example[], int minArguments, int reservedFirst, int reservedLast, bool addCurrentDirIfNoArguments, ReLogger* logger) : @@ -701,6 +703,7 @@ ReTool::ReTool(const char* usage[], const char* example[], int minArguments, m_filter(), m_start(time(NULL)), m_logger(logger) { +#pragma warning( pop ) } /** @@ -2387,7 +2390,6 @@ void ReDirTCP::doIt() { ReTCPClient client(m_logger); if (client.connect(ip, port)) { time_t start = time(NULL); - int64_t millisec; ReByteBuffer message; message.appendChar('x', bufferSize); time_t lastPrint = start; -- 2.39.5