From 46b5785d98ea1b23a9135897ff1a9b73f9a10bcb Mon Sep 17 00:00:00 2001 From: Alex Fabijanic Date: Fri, 25 Apr 2014 23:22:54 -0500 Subject: [PATCH] - fixed PS build script environment vars generation - fixed MongoDB 64-bit std::size_t warnings - added Thread::trySleep()/wakeUp() and tests --- Foundation/include/Poco/Runnable.h | 5 +++ Foundation/include/Poco/Thread.h | 19 +++++++++ Foundation/src/Runnable.cpp | 13 ++++++ Foundation/src/Thread.cpp | 14 +++++++ Foundation/testsuite/src/ThreadTest.cpp | 55 +++++++++++++++++++++++++ Foundation/testsuite/src/ThreadTest.h | 1 + MongoDB/include/Poco/MongoDB/Message.h | 5 ++- MongoDB/src/RequestMessage.cpp | 2 +- buildwin.ps1 | 18 ++++---- 9 files changed, 122 insertions(+), 10 deletions(-) diff --git a/Foundation/include/Poco/Runnable.h b/Foundation/include/Poco/Runnable.h index 17c78b0f1..bfe78d9a7 100644 --- a/Foundation/include/Poco/Runnable.h +++ b/Foundation/include/Poco/Runnable.h @@ -58,6 +58,11 @@ public: virtual void run() = 0; /// Do whatever the thread needs to do. Must /// be overridden by subclasses. + +protected: + void sleep(long milliseconds); + + void trySleep(long milliseconds); }; diff --git a/Foundation/include/Poco/Thread.h b/Foundation/include/Poco/Thread.h index 6ddbcda00..7b5c4aeb5 100644 --- a/Foundation/include/Poco/Thread.h +++ b/Foundation/include/Poco/Thread.h @@ -41,6 +41,7 @@ #include "Poco/Foundation.h" +#include "Poco/Event.h" #include "Poco/Mutex.h" @@ -186,6 +187,23 @@ public: bool isRunning() const; /// Returns true if the thread is running. + void trySleep(long milliseconds); + /// Starts an interruptible sleep. Thread will remain suspended + /// until (a) the timeout expires or (b) wakeUp() is called. + /// The trySleep()/wakeUp() pair of fnctions should be used with + /// understanding that this suspended state is not a true sleep, + /// but rather a state of waiting for an event, with timeout + /// expiration. This in essence means that calling wakeUp() + /// before calling trySleep() will prevent the next trySleep() + /// call to actually suspend the thread (which, in some scenarios, + /// may be desirable behavior). + + void wakeUp(); + /// Wakes up the thread which is in the state of interruptible + /// sleep. For threads that are not suspended, calling this + /// function has the effect of preventing the subsequent + /// trySleep() call to put thread in a suspended state. + static void sleep(long milliseconds); /// Suspends the current thread for the specified /// amount of time. @@ -220,6 +238,7 @@ private: int _id; std::string _name; ThreadLocalStorage* _pTLS; + Event _event; mutable FastMutex _mutex; friend class ThreadLocalStorage; diff --git a/Foundation/src/Runnable.cpp b/Foundation/src/Runnable.cpp index 7b64be628..f3822ca4d 100644 --- a/Foundation/src/Runnable.cpp +++ b/Foundation/src/Runnable.cpp @@ -35,6 +35,7 @@ #include "Poco/Runnable.h" +#include "Poco/Thread.h" namespace Poco { @@ -50,4 +51,16 @@ Runnable::~Runnable() } +void Runnable::sleep(long milliseconds) +{ + Thread::sleep(milliseconds); +} + + +void Runnable::trySleep(long milliseconds) +{ + Thread::current()->trySleep(milliseconds); +} + + } // namespace Poco diff --git a/Foundation/src/Thread.cpp b/Foundation/src/Thread.cpp index d28cae59a..530feb19b 100644 --- a/Foundation/src/Thread.cpp +++ b/Foundation/src/Thread.cpp @@ -62,6 +62,7 @@ Thread::Thread(): _name(makeName()), _pTLS(0) { + _event.reset(); } @@ -70,6 +71,7 @@ Thread::Thread(const std::string& name): _name(name), _pTLS(0) { + _event.reset(); } @@ -122,6 +124,18 @@ bool Thread::tryJoin(long milliseconds) } +void Thread::trySleep(long milliseconds) +{ + _event.tryWait(milliseconds); + _event.reset(); +} + +void Thread::wakeUp() +{ + _event.set(); +} + + ThreadLocalStorage& Thread::tls() { if (!_pTLS) diff --git a/Foundation/testsuite/src/ThreadTest.cpp b/Foundation/testsuite/src/ThreadTest.cpp index 9dd20962c..7cf58cf6f 100644 --- a/Foundation/testsuite/src/ThreadTest.cpp +++ b/Foundation/testsuite/src/ThreadTest.cpp @@ -134,6 +134,33 @@ private: }; +class TrySleepRunnable : public Runnable +{ +public: + TrySleepRunnable() : _counter(0) + { + } + + void run() + { + trySleep(300000); + ++_counter; + trySleep(300000); + ++_counter; + trySleep(10); + ++_counter; + } + + int counter() const + { + return _counter; + } + +private: + int _counter; +}; + + ThreadTest::ThreadTest(const std::string& name): CppUnit::TestCase(name) { } @@ -264,6 +291,33 @@ void ThreadTest::testNotJoin() } +void ThreadTest::testTrySleep() +{ + Thread thread; + TrySleepRunnable r; + assert(!thread.isRunning()); + assert(r.counter() == 0); + thread.start(r); + assert(thread.isRunning()); + assert(r.counter() == 0); + Thread::sleep(100); + assert(r.counter() == 0); + thread.wakeUp(); + Thread::sleep(10); + assert(r.counter() == 1); + Thread::sleep(100); + assert(r.counter() == 1); + thread.wakeUp(); + Thread::sleep(10); + assert(r.counter() == 2); + Thread::sleep(100); + assert(r.counter() == 3); + assert(!thread.isRunning()); + thread.wakeUp(); + assert(!thread.isRunning()); +} + + void ThreadTest::testNotRun() { Thread thread; @@ -389,6 +443,7 @@ CppUnit::Test* ThreadTest::suite() CppUnit_addTest(pSuite, ThreadTest, testNotJoin); CppUnit_addTest(pSuite, ThreadTest, testNotRun); CppUnit_addTest(pSuite, ThreadTest, testNotRunJoin); + CppUnit_addTest(pSuite, ThreadTest, testTrySleep); CppUnit_addTest(pSuite, ThreadTest, testThreadTarget); CppUnit_addTest(pSuite, ThreadTest, testThreadFunction); CppUnit_addTest(pSuite, ThreadTest, testThreadStackSize); diff --git a/Foundation/testsuite/src/ThreadTest.h b/Foundation/testsuite/src/ThreadTest.h index a4dd3655b..159adad23 100644 --- a/Foundation/testsuite/src/ThreadTest.h +++ b/Foundation/testsuite/src/ThreadTest.h @@ -54,6 +54,7 @@ public: void testNotJoin(); void testNotRun(); void testNotRunJoin(); + void testTrySleep(); void testThreadTarget(); void testThreadFunction(); void testThreadStackSize(); diff --git a/MongoDB/include/Poco/MongoDB/Message.h b/MongoDB/include/Poco/MongoDB/Message.h index 67a67b2b7..78aa5f83a 100644 --- a/MongoDB/include/Poco/MongoDB/Message.h +++ b/MongoDB/include/Poco/MongoDB/Message.h @@ -68,7 +68,7 @@ public: protected: MessageHeader _header; - void messageLength(std::size_t length); + void messageLength(Poco::Int32 length); /// Sets the message length in the message header }; @@ -79,8 +79,9 @@ inline MessageHeader& Message::header() } -inline void Message::messageLength(std::size_t length) +inline void Message::messageLength(Poco::Int32 length) { + poco_assert(length > 0); _header.setMessageLength(length); } diff --git a/MongoDB/src/RequestMessage.cpp b/MongoDB/src/RequestMessage.cpp index 2f86a8d9f..9d78b259d 100644 --- a/MongoDB/src/RequestMessage.cpp +++ b/MongoDB/src/RequestMessage.cpp @@ -62,7 +62,7 @@ void RequestMessage::send(std::ostream& ostr) buildRequest(requestWriter); requestWriter.flush(); - messageLength(static_cast(ss.tellp())); + messageLength(static_cast(ss.tellp())); BinaryWriter socketWriter(ostr, BinaryWriter::LITTLE_ENDIAN_BYTE_ORDER); _header.write(socketWriter); diff --git a/buildwin.ps1 b/buildwin.ps1 index ac690826f..9f4a97ea6 100644 --- a/buildwin.ps1 +++ b/buildwin.ps1 @@ -64,8 +64,12 @@ function Add-Env-Var([string] $lib, [string] $var) { if ((${Env:$var} -eq $null) -or (-not ${Env:$var}.Contains(${Env:$lib_$var"}))) { - ${Env:$var} = ${Env:$lib_$var;$Env:$var} + $libvar = "$lib" + "_" + "$var" + $envvar = [Environment]::GetEnvironmentVariable($libvar, "Process") + [Environment]::SetEnvironmentVariable($var, $envvar, "Process") + $envvar = [Environment]::GetEnvironmentVariable($var, "Process") } + } @@ -88,17 +92,20 @@ function Set-Environment } } + if (-Not $Env:PATH.Contains("$Env:POCO_BASE\bin64;$Env:POCO_BASE\bin;")) + { $Env:PATH = "$Env:POCO_BASE\bin64;$Env:POCO_BASE\bin;$Env:PATH" } + if ($openssl_base -eq '') { if ($platform -eq 'x64') { $script:openssl_base = 'C:\OpenSSL-Win64' } else { $script:openssl_base = 'C:\OpenSSL-Win32' } } - + $Env:OPENSSL_DIR = "$openssl_base" $Env:OPENSSL_INCLUDE = "$Env:OPENSSL_DIR\include" $Env:OPENSSL_LIB = "$Env:OPENSSL_DIR\lib;$Env:OPENSSL_DIR\lib\VC" - Add-Env-Var "OPENSSL", "INCLUDE" - Add-Env-Var "OPENSSL", "LIB" + Add-Env-Var "OPENSSL" "INCLUDE" + Add-Env-Var "OPENSSL" "LIB" if ($mysql_base -ne '') { @@ -109,9 +116,6 @@ function Set-Environment Add-Env-Var "MYSQL", "LIB" } - if (-Not $Env:PATH.Contains("$Env:POCO_BASE\bin64;$Env:POCO_BASE\bin;")) - { $Env:PATH = "$Env:POCO_BASE\bin64;$Env:POCO_BASE\bin;$Env:PATH" } - $vsct = "VS$($vs_version)COMNTOOLS" $vsdir = (Get-Item Env:$vsct).Value $Command = ''