mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-23 16:48:06 +02:00
Merge branch 'develop' of https://github.com/pocoproject/poco into develop
This commit is contained in:
@@ -33,7 +33,7 @@ matrix:
|
|||||||
|
|
||||||
- env: TEST_NAME="arm-linux-gnueabi- (make)"
|
- env: TEST_NAME="arm-linux-gnueabi- (make)"
|
||||||
script:
|
script:
|
||||||
- ./configure --omit=Data/ODBC,Data/MySQL,Crypto,NetSSL && make -s -j2 CROSS_COMPILE=arm-linux-gnueabi- POCO_TARGET_OSARCH=armv7l
|
- ./configure --omit=Data/ODBC,Data/MySQL,Crypto,NetSSL,PageCompiler && make -s -j2 CROSS_COMPILE=arm-linux-gnueabi- POCO_TARGET_OSARCH=armv7l
|
||||||
|
|
||||||
- env: TEST_NAME="gcc (CMake)"
|
- env: TEST_NAME="gcc (CMake)"
|
||||||
compiler: gcc
|
compiler: gcc
|
||||||
|
@@ -122,7 +122,7 @@ public:
|
|||||||
/// May return 0 if the priority has not been explicitly set.
|
/// May return 0 if the priority has not been explicitly set.
|
||||||
|
|
||||||
static int getMinOSPriority(int policy = POLICY_DEFAULT);
|
static int getMinOSPriority(int policy = POLICY_DEFAULT);
|
||||||
/// Returns the mininum operating system-specific priority value,
|
/// Returns the minimum operating system-specific priority value,
|
||||||
/// which can be passed to setOSPriority() for the given policy.
|
/// which can be passed to setOSPriority() for the given policy.
|
||||||
|
|
||||||
static int getMaxOSPriority(int policy = POLICY_DEFAULT);
|
static int getMaxOSPriority(int policy = POLICY_DEFAULT);
|
||||||
@@ -149,6 +149,13 @@ public:
|
|||||||
void start(Callable target, void* pData = 0);
|
void start(Callable target, void* pData = 0);
|
||||||
/// Starts the thread with the given target and parameter.
|
/// Starts the thread with the given target and parameter.
|
||||||
|
|
||||||
|
template <class Functor>
|
||||||
|
void startFunc(Functor fn)
|
||||||
|
/// Starts the thread with the given functor object or lambda.
|
||||||
|
{
|
||||||
|
startImpl(new FunctorRunnable<Functor>(fn));
|
||||||
|
}
|
||||||
|
|
||||||
void join();
|
void join();
|
||||||
/// Waits until the thread completes execution.
|
/// Waits until the thread completes execution.
|
||||||
/// If multiple threads try to join the same
|
/// If multiple threads try to join the same
|
||||||
@@ -221,7 +228,29 @@ protected:
|
|||||||
|
|
||||||
static int uniqueId();
|
static int uniqueId();
|
||||||
/// Creates and returns a unique id for a thread.
|
/// Creates and returns a unique id for a thread.
|
||||||
|
|
||||||
|
template <class Functor>
|
||||||
|
class FunctorRunnable: public Runnable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FunctorRunnable(const Functor& functor):
|
||||||
|
_functor(functor)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~FunctorRunnable()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void run()
|
||||||
|
{
|
||||||
|
_functor();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Functor _functor;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Thread(const Thread&);
|
Thread(const Thread&);
|
||||||
Thread& operator = (const Thread&);
|
Thread& operator = (const Thread&);
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#include "Poco/Event.h"
|
#include "Poco/Event.h"
|
||||||
#include "Poco/RefCountedObject.h"
|
#include "Poco/RefCountedObject.h"
|
||||||
#include "Poco/AutoPtr.h"
|
#include "Poco/AutoPtr.h"
|
||||||
|
#include "Poco/SharedPtr.h"
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
// must be limits.h (not <climits>) for PTHREAD_STACK_MIN on Solaris
|
// must be limits.h (not <climits>) for PTHREAD_STACK_MIN on Solaris
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
@@ -61,16 +62,6 @@ public:
|
|||||||
POLICY_DEFAULT_IMPL = SCHED_OTHER
|
POLICY_DEFAULT_IMPL = SCHED_OTHER
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CallbackData: public RefCountedObject
|
|
||||||
{
|
|
||||||
CallbackData(): callback(0), pData(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Callable callback;
|
|
||||||
void* pData;
|
|
||||||
};
|
|
||||||
|
|
||||||
ThreadImpl();
|
ThreadImpl();
|
||||||
~ThreadImpl();
|
~ThreadImpl();
|
||||||
|
|
||||||
@@ -83,9 +74,7 @@ public:
|
|||||||
static int getMaxOSPriorityImpl(int policy);
|
static int getMaxOSPriorityImpl(int policy);
|
||||||
void setStackSizeImpl(int size);
|
void setStackSizeImpl(int size);
|
||||||
int getStackSizeImpl() const;
|
int getStackSizeImpl() const;
|
||||||
void startImpl(Runnable& target);
|
void startImpl(SharedPtr<Runnable> pTarget);
|
||||||
void startImpl(Callable target, void* pData = 0);
|
|
||||||
|
|
||||||
void joinImpl();
|
void joinImpl();
|
||||||
bool joinImpl(long milliseconds);
|
bool joinImpl(long milliseconds);
|
||||||
bool isRunningImpl() const;
|
bool isRunningImpl() const;
|
||||||
@@ -96,7 +85,6 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void* runnableEntry(void* pThread);
|
static void* runnableEntry(void* pThread);
|
||||||
static void* callableEntry(void* pThread);
|
|
||||||
static int mapPrio(int prio, int policy = SCHED_OTHER);
|
static int mapPrio(int prio, int policy = SCHED_OTHER);
|
||||||
static int reverseMapPrio(int osPrio, int policy = SCHED_OTHER);
|
static int reverseMapPrio(int osPrio, int policy = SCHED_OTHER);
|
||||||
|
|
||||||
@@ -129,8 +117,6 @@ private:
|
|||||||
struct ThreadData: public RefCountedObject
|
struct ThreadData: public RefCountedObject
|
||||||
{
|
{
|
||||||
ThreadData():
|
ThreadData():
|
||||||
pRunnableTarget(0),
|
|
||||||
pCallbackTarget(0),
|
|
||||||
thread(0),
|
thread(0),
|
||||||
prio(PRIO_NORMAL_IMPL),
|
prio(PRIO_NORMAL_IMPL),
|
||||||
policy(SCHED_OTHER),
|
policy(SCHED_OTHER),
|
||||||
@@ -146,8 +132,7 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Runnable* pRunnableTarget;
|
SharedPtr<Runnable> pRunnableTarget;
|
||||||
AutoPtr<CallbackData> pCallbackTarget;
|
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
int prio;
|
int prio;
|
||||||
int osPrio;
|
int osPrio;
|
||||||
@@ -186,8 +171,7 @@ inline int ThreadImpl::getOSPriorityImpl() const
|
|||||||
|
|
||||||
inline bool ThreadImpl::isRunningImpl() const
|
inline bool ThreadImpl::isRunningImpl() const
|
||||||
{
|
{
|
||||||
return _pData->pRunnableTarget != 0 ||
|
return !_pData->pRunnableTarget.isNull();
|
||||||
(_pData->pCallbackTarget.get() != 0 && _pData->pCallbackTarget->callback != 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "Poco/Foundation.h"
|
#include "Poco/Foundation.h"
|
||||||
#include "Poco/Runnable.h"
|
#include "Poco/Runnable.h"
|
||||||
|
#include "Poco/SharedPtr.h"
|
||||||
#include "Poco/UnWindows.h"
|
#include "Poco/UnWindows.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -40,16 +41,6 @@ public:
|
|||||||
typedef unsigned (__stdcall *Entry)(void*);
|
typedef unsigned (__stdcall *Entry)(void*);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct CallbackData
|
|
||||||
{
|
|
||||||
CallbackData(): callback(0), pData(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Callable callback;
|
|
||||||
void* pData;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Priority
|
enum Priority
|
||||||
{
|
{
|
||||||
PRIO_LOWEST_IMPL = THREAD_PRIORITY_LOWEST,
|
PRIO_LOWEST_IMPL = THREAD_PRIORITY_LOWEST,
|
||||||
@@ -76,9 +67,7 @@ public:
|
|||||||
static int getMaxOSPriorityImpl(int policy);
|
static int getMaxOSPriorityImpl(int policy);
|
||||||
void setStackSizeImpl(int size);
|
void setStackSizeImpl(int size);
|
||||||
int getStackSizeImpl() const;
|
int getStackSizeImpl() const;
|
||||||
void startImpl(Runnable& target);
|
void startImpl(SharedPtr<Runnable> pTarget);
|
||||||
void startImpl(Callable target, void* pData = 0);
|
|
||||||
|
|
||||||
void joinImpl();
|
void joinImpl();
|
||||||
bool joinImpl(long milliseconds);
|
bool joinImpl(long milliseconds);
|
||||||
bool isRunningImpl() const;
|
bool isRunningImpl() const;
|
||||||
@@ -94,12 +83,6 @@ protected:
|
|||||||
static unsigned __stdcall runnableEntry(void* pThread);
|
static unsigned __stdcall runnableEntry(void* pThread);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_DLL)
|
|
||||||
static DWORD WINAPI callableEntry(LPVOID pThread);
|
|
||||||
#else
|
|
||||||
static unsigned __stdcall callableEntry(void* pThread);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void createImpl(Entry ent, void* pData);
|
void createImpl(Entry ent, void* pData);
|
||||||
void threadCleanup();
|
void threadCleanup();
|
||||||
|
|
||||||
@@ -129,12 +112,11 @@ private:
|
|||||||
DWORD _slot;
|
DWORD _slot;
|
||||||
};
|
};
|
||||||
|
|
||||||
Runnable* _pRunnableTarget;
|
SharedPtr<Runnable> _pRunnableTarget;
|
||||||
CallbackData _callbackTarget;
|
HANDLE _thread;
|
||||||
HANDLE _thread;
|
DWORD _threadId;
|
||||||
DWORD _threadId;
|
int _prio;
|
||||||
int _prio;
|
int _stackSize;
|
||||||
int _stackSize;
|
|
||||||
|
|
||||||
static CurrentThreadHolder _currentThreadHolder;
|
static CurrentThreadHolder _currentThreadHolder;
|
||||||
};
|
};
|
||||||
|
@@ -35,6 +35,9 @@ struct Foundation_API UTF8
|
|||||||
///
|
///
|
||||||
/// toUpper(), toUpperInPlace(), toLower() and toLowerInPlace() provide
|
/// toUpper(), toUpperInPlace(), toLower() and toLowerInPlace() provide
|
||||||
/// Unicode-based character case transformation for UTF-8 encoded strings.
|
/// Unicode-based character case transformation for UTF-8 encoded strings.
|
||||||
|
///
|
||||||
|
/// removeBOM() removes the UTF-8 Byte Order Mark sequence (0xEF, 0xBB, 0xBF)
|
||||||
|
/// from the beginning of the given string, if it's there.
|
||||||
{
|
{
|
||||||
static int icompare(const std::string& str, std::string::size_type pos, std::string::size_type n, std::string::const_iterator it2, std::string::const_iterator end2);
|
static int icompare(const std::string& str, std::string::size_type pos, std::string::size_type n, std::string::const_iterator it2, std::string::const_iterator end2);
|
||||||
static int icompare(const std::string& str1, const std::string& str2);
|
static int icompare(const std::string& str1, const std::string& str2);
|
||||||
@@ -51,6 +54,10 @@ struct Foundation_API UTF8
|
|||||||
static std::string& toUpperInPlace(std::string& str);
|
static std::string& toUpperInPlace(std::string& str);
|
||||||
static std::string toLower(const std::string& str);
|
static std::string toLower(const std::string& str);
|
||||||
static std::string& toLowerInPlace(std::string& str);
|
static std::string& toLowerInPlace(std::string& str);
|
||||||
|
|
||||||
|
static void removeBOM(std::string& str);
|
||||||
|
/// Remove the UTF-8 Byte Order Mark sequence (0xEF, 0xBB, 0xBF)
|
||||||
|
/// from the beginning of the string, if it's there.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -38,6 +38,57 @@
|
|||||||
namespace Poco {
|
namespace Poco {
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class RunnableHolder: public Runnable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RunnableHolder(Runnable& target):
|
||||||
|
_target(target)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~RunnableHolder()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void run()
|
||||||
|
{
|
||||||
|
_target.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Runnable& _target;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CallableHolder: public Runnable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CallableHolder(Thread::Callable callable, void* pData):
|
||||||
|
_callable(callable),
|
||||||
|
_pData(pData)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~CallableHolder()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void run()
|
||||||
|
{
|
||||||
|
_callable(_pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Thread::Callable _callable;
|
||||||
|
void* _pData;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
Thread::Thread():
|
Thread::Thread():
|
||||||
_id(uniqueId()),
|
_id(uniqueId()),
|
||||||
_name(makeName()),
|
_name(makeName()),
|
||||||
@@ -76,13 +127,13 @@ Thread::Priority Thread::getPriority() const
|
|||||||
|
|
||||||
void Thread::start(Runnable& target)
|
void Thread::start(Runnable& target)
|
||||||
{
|
{
|
||||||
startImpl(target);
|
startImpl(new RunnableHolder(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Thread::start(Callable target, void* pData)
|
void Thread::start(Callable target, void* pData)
|
||||||
{
|
{
|
||||||
startImpl(target, pData);
|
startImpl(new CallableHolder(target, pData));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -104,7 +104,10 @@ void ThreadImpl::setPriorityImpl(int prio)
|
|||||||
_pData->policy = SCHED_OTHER;
|
_pData->policy = SCHED_OTHER;
|
||||||
if (isRunningImpl())
|
if (isRunningImpl())
|
||||||
{
|
{
|
||||||
struct sched_param par;
|
struct sched_param par; struct MyStruct
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
par.sched_priority = mapPrio(_pData->prio, SCHED_OTHER);
|
par.sched_priority = mapPrio(_pData->prio, SCHED_OTHER);
|
||||||
if (pthread_setschedparam(_pData->thread, SCHED_OTHER, &par))
|
if (pthread_setschedparam(_pData->thread, SCHED_OTHER, &par))
|
||||||
throw SystemException("cannot set thread priority");
|
throw SystemException("cannot set thread priority");
|
||||||
@@ -117,7 +120,7 @@ void ThreadImpl::setOSPriorityImpl(int prio, int policy)
|
|||||||
{
|
{
|
||||||
if (prio != _pData->osPrio || policy != _pData->policy)
|
if (prio != _pData->osPrio || policy != _pData->policy)
|
||||||
{
|
{
|
||||||
if (_pData->pRunnableTarget || _pData->pCallbackTarget)
|
if (_pData->pRunnableTarget)
|
||||||
{
|
{
|
||||||
struct sched_param par;
|
struct sched_param par;
|
||||||
par.sched_priority = prio;
|
par.sched_priority = prio;
|
||||||
@@ -177,7 +180,7 @@ void ThreadImpl::setStackSizeImpl(int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ThreadImpl::startImpl(Runnable& target)
|
void ThreadImpl::startImpl(SharedPtr<Runnable> pTarget)
|
||||||
{
|
{
|
||||||
if (_pData->pRunnableTarget)
|
if (_pData->pRunnableTarget)
|
||||||
throw SystemException("thread already running");
|
throw SystemException("thread already running");
|
||||||
@@ -194,7 +197,7 @@ void ThreadImpl::startImpl(Runnable& target)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_pData->pRunnableTarget = ⌖
|
_pData->pRunnableTarget = pTarget;
|
||||||
if (pthread_create(&_pData->thread, &attributes, runnableEntry, this))
|
if (pthread_create(&_pData->thread, &attributes, runnableEntry, this))
|
||||||
{
|
{
|
||||||
_pData->pRunnableTarget = 0;
|
_pData->pRunnableTarget = 0;
|
||||||
@@ -224,56 +227,6 @@ void ThreadImpl::startImpl(Runnable& target)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ThreadImpl::startImpl(Callable target, void* pData)
|
|
||||||
{
|
|
||||||
if (_pData->pCallbackTarget && _pData->pCallbackTarget->callback)
|
|
||||||
throw SystemException("thread already running");
|
|
||||||
|
|
||||||
pthread_attr_t attributes;
|
|
||||||
pthread_attr_init(&attributes);
|
|
||||||
|
|
||||||
if (_pData->stackSize != 0)
|
|
||||||
{
|
|
||||||
if (0 != pthread_attr_setstacksize(&attributes, _pData->stackSize))
|
|
||||||
throw SystemException("can not set thread stack size");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 == _pData->pCallbackTarget.get())
|
|
||||||
_pData->pCallbackTarget = new CallbackData;
|
|
||||||
|
|
||||||
_pData->pCallbackTarget->callback = target;
|
|
||||||
_pData->pCallbackTarget->pData = pData;
|
|
||||||
|
|
||||||
if (pthread_create(&_pData->thread, &attributes, callableEntry, this))
|
|
||||||
{
|
|
||||||
_pData->pCallbackTarget->callback = 0;
|
|
||||||
_pData->pCallbackTarget->pData = 0;
|
|
||||||
pthread_attr_destroy(&attributes);
|
|
||||||
throw SystemException("cannot start thread");
|
|
||||||
}
|
|
||||||
_pData->started = true;
|
|
||||||
pthread_attr_destroy(&attributes);
|
|
||||||
|
|
||||||
if (_pData->policy == SCHED_OTHER)
|
|
||||||
{
|
|
||||||
if (_pData->prio != PRIO_NORMAL_IMPL)
|
|
||||||
{
|
|
||||||
struct sched_param par;
|
|
||||||
par.sched_priority = mapPrio(_pData->prio, SCHED_OTHER);
|
|
||||||
if (pthread_setschedparam(_pData->thread, SCHED_OTHER, &par))
|
|
||||||
throw SystemException("cannot set thread priority");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct sched_param par;
|
|
||||||
par.sched_priority = _pData->osPrio;
|
|
||||||
if (pthread_setschedparam(_pData->thread, _pData->policy, &par))
|
|
||||||
throw SystemException("cannot set thread priority");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ThreadImpl::joinImpl()
|
void ThreadImpl::joinImpl()
|
||||||
{
|
{
|
||||||
if (!_pData->started) return;
|
if (!_pData->started) return;
|
||||||
@@ -409,48 +362,6 @@ void* ThreadImpl::runnableEntry(void* pThread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void* ThreadImpl::callableEntry(void* pThread)
|
|
||||||
{
|
|
||||||
_currentThreadHolder.set(reinterpret_cast<ThreadImpl*>(pThread));
|
|
||||||
|
|
||||||
#if defined(POCO_OS_FAMILY_UNIX)
|
|
||||||
sigset_t sset;
|
|
||||||
sigemptyset(&sset);
|
|
||||||
sigaddset(&sset, SIGQUIT);
|
|
||||||
sigaddset(&sset, SIGTERM);
|
|
||||||
sigaddset(&sset, SIGPIPE);
|
|
||||||
pthread_sigmask(SIG_BLOCK, &sset, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ThreadImpl* pThreadImpl = reinterpret_cast<ThreadImpl*>(pThread);
|
|
||||||
#if defined(POCO_POSIX_DEBUGGER_THREAD_NAMES)
|
|
||||||
setThreadName(pThreadImpl->_pData->thread, reinterpret_cast<Thread*>(pThread)->getName().c_str());
|
|
||||||
#endif
|
|
||||||
AutoPtr<ThreadData> pData = pThreadImpl->_pData;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
pData->pCallbackTarget->callback(pData->pCallbackTarget->pData);
|
|
||||||
}
|
|
||||||
catch (Exception& exc)
|
|
||||||
{
|
|
||||||
ErrorHandler::handle(exc);
|
|
||||||
}
|
|
||||||
catch (std::exception& exc)
|
|
||||||
{
|
|
||||||
ErrorHandler::handle(exc);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
ErrorHandler::handle();
|
|
||||||
}
|
|
||||||
|
|
||||||
pData->pCallbackTarget->callback = 0;
|
|
||||||
pData->pCallbackTarget->pData = 0;
|
|
||||||
pData->done.set();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int ThreadImpl::mapPrio(int prio, int policy)
|
int ThreadImpl::mapPrio(int prio, int policy)
|
||||||
{
|
{
|
||||||
int pmin = getMinOSPriorityImpl(policy);
|
int pmin = getMinOSPriorityImpl(policy);
|
||||||
|
@@ -70,7 +70,6 @@ ThreadImpl::CurrentThreadHolder ThreadImpl::_currentThreadHolder;
|
|||||||
|
|
||||||
|
|
||||||
ThreadImpl::ThreadImpl():
|
ThreadImpl::ThreadImpl():
|
||||||
_pRunnableTarget(0),
|
|
||||||
_thread(0),
|
_thread(0),
|
||||||
_threadId(0),
|
_threadId(0),
|
||||||
_prio(PRIO_NORMAL_IMPL),
|
_prio(PRIO_NORMAL_IMPL),
|
||||||
@@ -105,30 +104,16 @@ void ThreadImpl::setOSPriorityImpl(int prio, int /* policy */)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ThreadImpl::startImpl(Runnable& target)
|
void ThreadImpl::startImpl(SharedPtr<Runnable> pTarget)
|
||||||
{
|
{
|
||||||
if (isRunningImpl())
|
if (isRunningImpl())
|
||||||
throw SystemException("thread already running");
|
throw SystemException("thread already running");
|
||||||
|
|
||||||
_pRunnableTarget = ⌖
|
_pRunnableTarget = pTarget;
|
||||||
|
|
||||||
createImpl(runnableEntry, this);
|
createImpl(runnableEntry, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ThreadImpl::startImpl(Callable target, void* pData)
|
|
||||||
{
|
|
||||||
if (isRunningImpl())
|
|
||||||
throw SystemException("thread already running");
|
|
||||||
|
|
||||||
threadCleanup();
|
|
||||||
_callbackTarget.callback = target;
|
|
||||||
_callbackTarget.pData = pData;
|
|
||||||
|
|
||||||
createImpl(callableEntry, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ThreadImpl::createImpl(Entry ent, void* pData)
|
void ThreadImpl::createImpl(Entry ent, void* pData)
|
||||||
{
|
{
|
||||||
#if defined(_DLL)
|
#if defined(_DLL)
|
||||||
@@ -237,35 +222,4 @@ unsigned __stdcall ThreadImpl::runnableEntry(void* pThread)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(_DLL)
|
|
||||||
DWORD WINAPI ThreadImpl::callableEntry(LPVOID pThread)
|
|
||||||
#else
|
|
||||||
unsigned __stdcall ThreadImpl::callableEntry(void* pThread)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
_currentThreadHolder.set(reinterpret_cast<ThreadImpl*>(pThread));
|
|
||||||
#if defined(POCO_WIN32_DEBUGGER_THREAD_NAMES)
|
|
||||||
setThreadName(-1, reinterpret_cast<Thread*>(pThread)->getName().c_str());
|
|
||||||
#endif
|
|
||||||
try
|
|
||||||
{
|
|
||||||
ThreadImpl* pTI = reinterpret_cast<ThreadImpl*>(pThread);
|
|
||||||
pTI->_callbackTarget.callback(pTI->_callbackTarget.pData);
|
|
||||||
}
|
|
||||||
catch (Exception& exc)
|
|
||||||
{
|
|
||||||
ErrorHandler::handle(exc);
|
|
||||||
}
|
|
||||||
catch (std::exception& exc)
|
|
||||||
{
|
|
||||||
ErrorHandler::handle(exc);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
ErrorHandler::handle();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Poco
|
} // namespace Poco
|
||||||
|
@@ -160,4 +160,16 @@ std::string& UTF8::toLowerInPlace(std::string& str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UTF8::removeBOM(std::string& str)
|
||||||
|
{
|
||||||
|
if (str.size() >= 3
|
||||||
|
&& static_cast<unsigned char>(str[0]) == 0xEF
|
||||||
|
&& static_cast<unsigned char>(str[1]) == 0xBB
|
||||||
|
&& static_cast<unsigned char>(str[2]) == 0xBF)
|
||||||
|
{
|
||||||
|
str.erase(0, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Poco
|
} // namespace Poco
|
||||||
|
@@ -363,6 +363,45 @@ void ThreadTest::testThreadFunction()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct Functor
|
||||||
|
{
|
||||||
|
void operator () ()
|
||||||
|
{
|
||||||
|
++MyRunnable::_staticVar;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void ThreadTest::testThreadFunctor()
|
||||||
|
{
|
||||||
|
Thread thread;
|
||||||
|
|
||||||
|
assert (!thread.isRunning());
|
||||||
|
|
||||||
|
MyRunnable::_staticVar = 0;
|
||||||
|
thread.startFunc(Functor());
|
||||||
|
thread.join();
|
||||||
|
assert (1 == MyRunnable::_staticVar);
|
||||||
|
|
||||||
|
assert (!thread.isRunning());
|
||||||
|
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
|
||||||
|
Thread thread2;
|
||||||
|
|
||||||
|
assert (!thread2.isRunning());
|
||||||
|
|
||||||
|
MyRunnable::_staticVar = 0;
|
||||||
|
thread.startFunc([] () {MyRunnable::_staticVar++;});
|
||||||
|
thread.join();
|
||||||
|
assert (1 == MyRunnable::_staticVar);
|
||||||
|
|
||||||
|
assert (!thread2.isRunning());
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ThreadTest::testThreadStackSize()
|
void ThreadTest::testThreadStackSize()
|
||||||
{
|
{
|
||||||
int stackSize = 50000000;
|
int stackSize = 50000000;
|
||||||
@@ -436,6 +475,7 @@ CppUnit::Test* ThreadTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ThreadTest, testTrySleep);
|
CppUnit_addTest(pSuite, ThreadTest, testTrySleep);
|
||||||
CppUnit_addTest(pSuite, ThreadTest, testThreadTarget);
|
CppUnit_addTest(pSuite, ThreadTest, testThreadTarget);
|
||||||
CppUnit_addTest(pSuite, ThreadTest, testThreadFunction);
|
CppUnit_addTest(pSuite, ThreadTest, testThreadFunction);
|
||||||
|
CppUnit_addTest(pSuite, ThreadTest, testThreadFunctor);
|
||||||
CppUnit_addTest(pSuite, ThreadTest, testThreadStackSize);
|
CppUnit_addTest(pSuite, ThreadTest, testThreadStackSize);
|
||||||
CppUnit_addTest(pSuite, ThreadTest, testSleep);
|
CppUnit_addTest(pSuite, ThreadTest, testSleep);
|
||||||
|
|
||||||
|
@@ -37,6 +37,7 @@ public:
|
|||||||
void testTrySleep();
|
void testTrySleep();
|
||||||
void testThreadTarget();
|
void testThreadTarget();
|
||||||
void testThreadFunction();
|
void testThreadFunction();
|
||||||
|
void testThreadFunctor();
|
||||||
void testThreadStackSize();
|
void testThreadStackSize();
|
||||||
void testSleep();
|
void testSleep();
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// HTTPClientSession.h
|
// HTTPClientSession.h
|
||||||
//
|
//
|
||||||
// $Id: //poco/1.4/Net/include/Poco/Net/HTTPClientSession.h#7 $
|
// $Id: //poco/1.4/Net/include/Poco/Net/HTTPClientSession.h#8 $
|
||||||
//
|
//
|
||||||
// Library: Net
|
// Library: Net
|
||||||
// Package: HTTPClient
|
// Package: HTTPClient
|
||||||
@@ -100,6 +100,9 @@ public:
|
|||||||
HTTPClientSession(const std::string& host, Poco::UInt16 port = HTTPSession::HTTP_PORT);
|
HTTPClientSession(const std::string& host, Poco::UInt16 port = HTTPSession::HTTP_PORT);
|
||||||
/// Creates a HTTPClientSession using the given host and port.
|
/// Creates a HTTPClientSession using the given host and port.
|
||||||
|
|
||||||
|
HTTPClientSession(const std::string& host, Poco::UInt16 port, const ProxyConfig& proxyConfig);
|
||||||
|
/// Creates a HTTPClientSession using the given host, port and proxy configuration.
|
||||||
|
|
||||||
virtual ~HTTPClientSession();
|
virtual ~HTTPClientSession();
|
||||||
/// Destroys the HTTPClientSession and closes
|
/// Destroys the HTTPClientSession and closes
|
||||||
/// the underlying socket.
|
/// the underlying socket.
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "Poco/URI.h"
|
#include "Poco/URI.h"
|
||||||
#include "Poco/String.h"
|
#include "Poco/String.h"
|
||||||
#include "Poco/CountingStream.h"
|
#include "Poco/CountingStream.h"
|
||||||
|
#include "Poco/UTF8String.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
@@ -42,20 +43,31 @@ namespace Poco {
|
|||||||
namespace Net {
|
namespace Net {
|
||||||
|
|
||||||
|
|
||||||
const std::string HTMLForm::ENCODING_URL = "application/x-www-form-urlencoded";
|
const std::string HTMLForm::ENCODING_URL = "application/x-www-form-urlencoded";
|
||||||
const std::string HTMLForm::ENCODING_MULTIPART = "multipart/form-data";
|
const std::string HTMLForm::ENCODING_MULTIPART = "multipart/form-data";
|
||||||
const int HTMLForm::UNKNOWN_CONTENT_LENGTH = -1;
|
const int HTMLForm::UNKNOWN_CONTENT_LENGTH = -1;
|
||||||
|
|
||||||
|
|
||||||
class HTMLFormCountingOutputStream : public CountingOutputStream
|
class HTMLFormCountingOutputStream: public CountingOutputStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HTMLFormCountingOutputStream() : _isvalid(true) {}
|
HTMLFormCountingOutputStream():
|
||||||
|
_valid(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValid() const
|
||||||
|
{
|
||||||
|
return _valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValid(bool v)
|
||||||
|
{
|
||||||
|
_valid = v;
|
||||||
|
}
|
||||||
|
|
||||||
bool getIsValid() const { return _isvalid; }
|
|
||||||
void setIsValid(bool v) { _isvalid = v; }
|
|
||||||
private:
|
private:
|
||||||
bool _isvalid;
|
bool _valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -238,7 +250,7 @@ std::streamsize HTMLForm::calculateContentLength()
|
|||||||
|
|
||||||
HTMLFormCountingOutputStream c;
|
HTMLFormCountingOutputStream c;
|
||||||
write(c);
|
write(c);
|
||||||
if (c.getIsValid())
|
if (c.isValid())
|
||||||
return c.chars();
|
return c.chars();
|
||||||
else
|
else
|
||||||
return UNKNOWN_CONTENT_LENGTH;
|
return UNKNOWN_CONTENT_LENGTH;
|
||||||
@@ -274,6 +286,7 @@ void HTMLForm::readUrl(std::istream& istr)
|
|||||||
|
|
||||||
int fields = 0;
|
int fields = 0;
|
||||||
int ch = istr.get();
|
int ch = istr.get();
|
||||||
|
bool isFirst = true;
|
||||||
while (ch != eof)
|
while (ch != eof)
|
||||||
{
|
{
|
||||||
if (_fieldLimit > 0 && fields == _fieldLimit)
|
if (_fieldLimit > 0 && fields == _fieldLimit)
|
||||||
@@ -296,6 +309,11 @@ void HTMLForm::readUrl(std::istream& istr)
|
|||||||
ch = istr.get();
|
ch = istr.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// remove UTF-8 byte order mark from first name, if present
|
||||||
|
if (isFirst)
|
||||||
|
{
|
||||||
|
UTF8::removeBOM(name);
|
||||||
|
}
|
||||||
std::string decodedName;
|
std::string decodedName;
|
||||||
std::string decodedValue;
|
std::string decodedValue;
|
||||||
URI::decode(name, decodedName);
|
URI::decode(name, decodedName);
|
||||||
@@ -303,6 +321,7 @@ void HTMLForm::readUrl(std::istream& istr)
|
|||||||
add(decodedName, decodedValue);
|
add(decodedName, decodedValue);
|
||||||
++fields;
|
++fields;
|
||||||
if (ch == '&') ch = istr.get();
|
if (ch == '&') ch = istr.get();
|
||||||
|
isFirst = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,7 +421,7 @@ void HTMLForm::writeMultipart(std::ostream& ostr)
|
|||||||
if (partlen != PartSource::UNKNOWN_CONTENT_LENGTH)
|
if (partlen != PartSource::UNKNOWN_CONTENT_LENGTH)
|
||||||
costr->addChars(static_cast<int>(partlen));
|
costr->addChars(static_cast<int>(partlen));
|
||||||
else
|
else
|
||||||
costr->setIsValid(false);
|
costr->setValid(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
StreamCopier::copyStream(ita->pSource->stream(), ostr);
|
StreamCopier::copyStream(ita->pSource->stream(), ostr);
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// HTTPClientSession.cpp
|
// HTTPClientSession.cpp
|
||||||
//
|
//
|
||||||
// $Id: //poco/1.4/Net/src/HTTPClientSession.cpp#14 $
|
// $Id: //poco/1.4/Net/src/HTTPClientSession.cpp#15 $
|
||||||
//
|
//
|
||||||
// Library: Net
|
// Library: Net
|
||||||
// Package: HTTPClient
|
// Package: HTTPClient
|
||||||
@@ -87,6 +87,18 @@ HTTPClientSession::HTTPClientSession(const std::string& host, Poco::UInt16 port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HTTPClientSession::HTTPClientSession(const std::string& host, Poco::UInt16 port, const ProxyConfig& proxyConfig):
|
||||||
|
_host(host),
|
||||||
|
_port(port),
|
||||||
|
_proxyConfig(proxyConfig),
|
||||||
|
_keepAliveTimeout(DEFAULT_KEEP_ALIVE_TIMEOUT, 0),
|
||||||
|
_reconnect(false),
|
||||||
|
_mustReconnect(false),
|
||||||
|
_expectResponseBody(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
HTTPClientSession::~HTTPClientSession()
|
HTTPClientSession::~HTTPClientSession()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -379,7 +391,8 @@ void HTTPClientSession::proxyAuthenticateImpl(HTTPRequest& request)
|
|||||||
|
|
||||||
StreamSocket HTTPClientSession::proxyConnect()
|
StreamSocket HTTPClientSession::proxyConnect()
|
||||||
{
|
{
|
||||||
HTTPClientSession proxySession(getProxyHost(), getProxyPort());
|
ProxyConfig emptyProxyConfig;
|
||||||
|
HTTPClientSession proxySession(getProxyHost(), getProxyPort(), emptyProxyConfig);
|
||||||
proxySession.setTimeout(getTimeout());
|
proxySession.setTimeout(getTimeout());
|
||||||
std::string targetAddress(_host);
|
std::string targetAddress(_host);
|
||||||
targetAddress.append(":");
|
targetAddress.append(":");
|
||||||
|
@@ -191,6 +191,20 @@ void HTMLFormTest::testReadUrlPUT()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void HTMLFormTest::testReadUrlBOM()
|
||||||
|
{
|
||||||
|
HTTPRequest req("PUT", "/form.cgi?field0=value0");
|
||||||
|
std::istringstream istr("\357\273\277field1=value1&field2=value%202&field3=value%3D3&field4=value%264");
|
||||||
|
HTMLForm form(req, istr);
|
||||||
|
assert (form.size() == 5);
|
||||||
|
assert (form["field0"] == "value0");
|
||||||
|
assert (form["field1"] == "value1");
|
||||||
|
assert (form["field2"] == "value 2");
|
||||||
|
assert (form["field3"] == "value=3");
|
||||||
|
assert (form["field4"] == "value&4");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void HTMLFormTest::testReadMultipart()
|
void HTMLFormTest::testReadMultipart()
|
||||||
{
|
{
|
||||||
std::istringstream istr(
|
std::istringstream istr(
|
||||||
@@ -359,6 +373,7 @@ CppUnit::Test* HTMLFormTest::suite()
|
|||||||
CppUnit_addTest(pSuite, HTMLFormTest, testReadUrlGET);
|
CppUnit_addTest(pSuite, HTMLFormTest, testReadUrlGET);
|
||||||
CppUnit_addTest(pSuite, HTMLFormTest, testReadUrlPOST);
|
CppUnit_addTest(pSuite, HTMLFormTest, testReadUrlPOST);
|
||||||
CppUnit_addTest(pSuite, HTMLFormTest, testReadUrlPUT);
|
CppUnit_addTest(pSuite, HTMLFormTest, testReadUrlPUT);
|
||||||
|
CppUnit_addTest(pSuite, HTMLFormTest, testReadUrlBOM);
|
||||||
CppUnit_addTest(pSuite, HTMLFormTest, testReadMultipart);
|
CppUnit_addTest(pSuite, HTMLFormTest, testReadMultipart);
|
||||||
CppUnit_addTest(pSuite, HTMLFormTest, testSubmit1);
|
CppUnit_addTest(pSuite, HTMLFormTest, testSubmit1);
|
||||||
CppUnit_addTest(pSuite, HTMLFormTest, testSubmit2);
|
CppUnit_addTest(pSuite, HTMLFormTest, testSubmit2);
|
||||||
|
@@ -31,6 +31,7 @@ public:
|
|||||||
void testReadUrlGET();
|
void testReadUrlGET();
|
||||||
void testReadUrlPOST();
|
void testReadUrlPOST();
|
||||||
void testReadUrlPUT();
|
void testReadUrlPUT();
|
||||||
|
void testReadUrlBOM();
|
||||||
void testReadMultipart();
|
void testReadMultipart();
|
||||||
void testSubmit1();
|
void testSubmit1();
|
||||||
void testSubmit2();
|
void testSubmit2();
|
||||||
|
Reference in New Issue
Block a user