1//
2// Thread.cpp
3//
4// Library: Foundation
5// Package: Threading
6// Module: Thread
7//
8// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/Thread.h"
16#include "Poco/Mutex.h"
17#include "Poco/Exception.h"
18#include "Poco/ThreadLocal.h"
19#include "Poco/AtomicCounter.h"
20#include <sstream>
21#include "Thread_STD.cpp"
22
23
24namespace Poco {
25
26
27namespace {
28
29class RunnableHolder: public Runnable
30{
31public:
32 RunnableHolder(Runnable& target):
33 _target(target)
34 {
35 }
36
37 ~RunnableHolder()
38 {
39 }
40
41 void run()
42 {
43 _target.run();
44 }
45
46private:
47 Runnable& _target;
48};
49
50
51class CallableHolder: public Runnable
52{
53public:
54 CallableHolder(Thread::Callable callable, void* pData):
55 _callable(callable),
56 _pData(pData)
57 {
58 }
59
60 ~CallableHolder()
61 {
62 }
63
64 void run()
65 {
66 _callable(_pData);
67 }
68
69private:
70 Thread::Callable _callable;
71 void* _pData;
72};
73
74
75} // namespace
76
77
78Thread::Thread():
79 _id(uniqueId()),
80 _name(makeName()),
81 _pTLS(0),
82 _event()
83{
84}
85
86
87Thread::Thread(const std::string& rName):
88 _id(uniqueId()),
89 _name(rName),
90 _pTLS(0),
91 _event()
92{
93}
94
95
96Thread::~Thread()
97{
98 delete _pTLS;
99}
100
101
102void Thread::setPriority(Priority prio)
103{
104 setPriorityImpl(prio);
105}
106
107
108Thread::Priority Thread::getPriority() const
109{
110 return Priority(getPriorityImpl());
111}
112
113
114void Thread::start(Runnable& target)
115{
116 startImpl(new RunnableHolder(target));
117}
118
119
120void Thread::start(Callable target, void* pData)
121{
122 startImpl(new CallableHolder(target, pData));
123}
124
125
126void Thread::join()
127{
128 joinImpl();
129}
130
131
132void Thread::join(long milliseconds)
133{
134 if (!joinImpl(milliseconds))
135 throw TimeoutException();
136}
137
138
139bool Thread::tryJoin(long milliseconds)
140{
141 return joinImpl(milliseconds);
142}
143
144
145bool Thread::trySleep(long milliseconds)
146{
147 Thread* pT = Thread::current();
148 poco_check_ptr(pT);
149 return !(pT->_event.tryWait(milliseconds));
150}
151
152
153void Thread::wakeUp()
154{
155 _event.set();
156}
157
158
159ThreadLocalStorage& Thread::tls()
160{
161 if (!_pTLS)
162 _pTLS = new ThreadLocalStorage;
163 return *_pTLS;
164}
165
166
167void Thread::clearTLS()
168{
169 if (_pTLS)
170 {
171 delete _pTLS;
172 _pTLS = 0;
173 }
174}
175
176
177std::string Thread::makeName()
178{
179 std::ostringstream threadName;
180 threadName << '#' << _id;
181 return threadName.str();
182}
183
184
185int Thread::uniqueId()
186{
187 static Poco::AtomicCounter counter;
188 return ++counter;
189}
190
191
192void Thread::setName(const std::string& rName)
193{
194 FastMutex::ScopedLock lock(_mutex);
195
196 _name = rName;
197}
198
199
200} // namespace Poco
201