reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
ThreadIf.cxx
Go to the documentation of this file.
1#include "rutil/ThreadIf.hxx"
2
3#if defined(WIN32)
4#include <stdio.h>
5#include <tchar.h>
6#include <time.h>
7#ifdef _WIN32_WCE
8typedef LPTHREAD_START_ROUTINE RESIP_THREAD_START_ROUTINE;
9#else
10#include <process.h> // for _beginthreadex()
11typedef unsigned(__stdcall *RESIP_THREAD_START_ROUTINE)(void*);
12#endif
13
14//from Random.cxx
15#include "rutil/Socket.hxx"
16#endif
17
18#include "rutil/ResipAssert.h"
19#include <iostream>
20#include "rutil/ThreadIf.hxx"
21#include "rutil/Mutex.hxx"
22#include "rutil/Lock.hxx"
23#include "rutil/Socket.hxx"
24#include "rutil/Logger.hxx"
25
26#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
27
28using namespace resip;
29
30#ifdef WIN32
31ThreadIf::TlsDestructorMap *ThreadIf::mTlsDestructors;
32Mutex *ThreadIf::mTlsDestructorsMutex;
33#endif
34
35std::thread::id noThread;
36
37#ifdef WIN32
38unsigned int TlsDestructorInitializer::mInstanceCounter=0;
39TlsDestructorInitializer::TlsDestructorInitializer()
40{
41 if (mInstanceCounter++ == 0)
42 {
43 ThreadIf::mTlsDestructorsMutex = new Mutex();
44 ThreadIf::mTlsDestructors = new ThreadIf::TlsDestructorMap;
45 }
46}
47TlsDestructorInitializer::~TlsDestructorInitializer()
48{
49 if (--mInstanceCounter == 0)
50 {
51 delete ThreadIf::mTlsDestructorsMutex;
52 ThreadIf::mTlsDestructors->clear();
53 delete ThreadIf::mTlsDestructors;
54 }
55}
56#endif
57
58
60 mThreadObj(nullptr),
61 mId(),
62 mShutdown(false),
63 mShutdownMutex()
64{
65}
66
67
69{
70 shutdown();
71 join();
72}
73
74void
76{
78
79 mThreadObj = std::make_shared<std::thread>([this]
80 {
81 thread();
82#ifdef WIN32
83 // Free data in TLS slots.
84 ThreadIf::tlsDestroyAll();
85#endif
86 });
87 mId = mThreadObj->get_id();
88 return;
89}
90
91void
93{
94 // !kh!
95 // perhaps assert instead of returning when join()ed already?
96 // programming error?
97 //assert(mId == 0);
98
99 if (!mThreadObj)
100 {
101 return;
102 }
103
104 if(!mThreadObj->joinable())
105 {
106 return;
107 }
108
109 mThreadObj->join();
110
111 mThreadObj.reset();
112 mId = noThread;
113}
114
115void
117{
118 mThreadObj->detach();
119 mThreadObj.reset();
120 mId = noThread;
121}
122
125{
126 return std::this_thread::get_id();
127}
128
129int
130ThreadIf::tlsKeyCreate(TlsKey &key, TlsDestructor *destructor)
131{
132#if defined(WIN32)
133 key = TlsAlloc();
134 if (key!=TLS_OUT_OF_INDEXES)
135 {
136 Lock lock(*mTlsDestructorsMutex);
137 (*mTlsDestructors)[key] = destructor;
138 return 0;
139 }
140 else
141 {
142 return GetLastError();
143 }
144#else
145 return pthread_key_create(&key, destructor);
146#endif
147}
148
149int
151{
152#if defined(WIN32)
153 if (TlsFree(key)>0)
154 {
155 Lock lock(*mTlsDestructorsMutex);
156 mTlsDestructors->erase(key);
157 return 0;
158 }
159 else
160 {
161 return GetLastError();
162 }
163#else
164 return pthread_key_delete(key);
165#endif
166}
167
168int
169ThreadIf::tlsSetValue(TlsKey key, const void *val)
170{
171#if defined(WIN32)
172 return TlsSetValue(key, (LPVOID)val)>0?0:GetLastError();
173#else
174 return pthread_setspecific(key, val);
175#endif
176}
177
178void *
180{
181#if defined(WIN32)
182 return TlsGetValue(key);
183#else
184 return pthread_getspecific(key);
185#endif
186}
187
188
189void
191{
192 Lock lock(mShutdownMutex);
193 if (!mShutdown)
194 {
195 mShutdown = true;
196 mShutdownCondition.notify_one();
197 }
198}
199
200bool
202{
203 Lock lock(mShutdownMutex);
204 if(!mShutdown)
205 {
206 mShutdownCondition.wait_for(lock, std::chrono::milliseconds(ms));
207 }
208 return mShutdown;
209}
210
211bool
213{
214 Lock lock(mShutdownMutex);
215 (void)lock;
216 return ( mShutdown );
217}
218
219#ifdef WIN32
220void
221ThreadIf::tlsDestroyAll()
222{
223 Lock lock(*mTlsDestructorsMutex);
224 ThreadIf::TlsDestructorMap::const_iterator i = mTlsDestructors->begin();
225 while(i != mTlsDestructors->end())
226 {
227 void *val = TlsGetValue(i->first);
228 if (val != NULL)
229 {
230 (*(i->second))(val);
231 }
232 i++;
233 }
234}
235#endif
236
237// End of File
238
239/* ====================================================================
240 * The Vovida Software License, Version 1.0
241 *
242 * Copyright (c) 2000-2008 Vovida Networks, Inc. All rights reserved.
243 *
244 * Redistribution and use in source and binary forms, with or without
245 * modification, are permitted provided that the following conditions
246 * are met:
247 *
248 * 1. Redistributions of source code must retain the above copyright
249 * notice, this list of conditions and the following disclaimer.
250 *
251 * 2. Redistributions in binary form must reproduce the above copyright
252 * notice, this list of conditions and the following disclaimer in
253 * the documentation and/or other materials provided with the
254 * distribution.
255 *
256 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
257 * and "Vovida Open Communication Application Library (VOCAL)" must
258 * not be used to endorse or promote products derived from this
259 * software without prior written permission. For written
260 * permission, please contact vocal@vovida.org.
261 *
262 * 4. Products derived from this software may not be called "VOCAL", nor
263 * may "VOCAL" appear in their name, without prior written
264 * permission of Vovida Networks, Inc.
265 *
266 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
267 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
268 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
269 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
270 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
271 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
272 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
273 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
274 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
275 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
276 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
277 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
278 * DAMAGE.
279 *
280 * ====================================================================
281 *
282 * This software consists of voluntary contributions made by Vovida
283 * Networks, Inc. and many individuals on behalf of Vovida Networks,
284 * Inc. For more information on Vovida Networks, Inc., please see
285 * <http://www.vovida.org/>.
286 *
287 */
#define resip_assert(x)
This file needs to work for both C and C++ code.
Handles cross-platform sockets compatibility.
std::thread::id noThread
Definition ThreadIf.cxx:35
static void * tlsGetValue(TlsKey key)
This function follows pthread_getspecific() signature.
Definition ThreadIf.cxx:179
static int tlsKeyCreate(TlsKey &key, TlsDestructor *destructor)
This function follows pthread_key_create() signature.
Definition ThreadIf.cxx:130
std::shared_ptr< std::thread > mThreadObj
Definition ThreadIf.hxx:105
pthread_key_t TlsKey
Definition ThreadIf.hxx:85
virtual ~ThreadIf()
Definition ThreadIf.cxx:68
virtual void shutdown()
Definition ThreadIf.cxx:190
virtual void run()
Definition ThreadIf.cxx:75
static Id selfId()
Definition ThreadIf.cxx:124
static int tlsKeyDelete(TlsKey key)
This function follows pthread_key_delete() signature.
Definition ThreadIf.cxx:150
bool isShutdown() const
Definition ThreadIf.cxx:212
static int tlsSetValue(TlsKey key, const void *val)
This function follows pthread_setspecific() signature.
Definition ThreadIf.cxx:169
Condition mShutdownCondition
Definition ThreadIf.hxx:122
virtual bool waitForShutdown(int ms) const
Definition ThreadIf.cxx:201
virtual void thread()=0
std::thread::id Id
Definition ThreadIf.hxx:79
dcm! – add UnusedChecking(_enum) below;
std::mutex Mutex
A semaphore that can be locked by only one thread at a time.
Definition Mutex.hxx:37
std::unique_lock< Mutex > Lock
A convenience class to lock a Lockable (such as a Mutex) on object creation, and unlock on destructio...
Definition Lock.hxx:28