win32: fix compilation after the last commit
[deb_libcec.git] / src / lib / platform / posix / pthreads.cpp
CommitLineData
6f14b512
LOK
1/*
2 * This file is part of the libCEC(R) library.
3 *
4 * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited. All rights reserved.
5 * libCEC(R) is an original work, containing original code.
6 *
7 * libCEC(R) is a trademark of Pulse-Eight Limited.
8 *
9 * This program is dual-licensed; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 *
23 *
24 * Alternatively, you can license this library under a commercial license,
25 * please contact Pulse-Eight Licensing for more information.
26 *
27 * For more information contact:
28 * Pulse-Eight Licensing <license@pulse-eight.com>
29 * http://www.pulse-eight.com/
30 * http://www.pulse-eight.net/
31 */
32
33#include "../threads.h"
34#include "../timeutils.h"
35
36using namespace CEC;
37
38CMutex::CMutex(bool bRecursive /* = true */) :
39 IMutex(bRecursive)
40{
41 pthread_mutex_init(&m_mutex, bRecursive ? GetMutexAttribute() : NULL);
42}
43
44CMutex::~CMutex(void)
45{
46 pthread_mutex_destroy(&m_mutex);
47}
48
49bool CMutex::TryLock(void)
50{
51 return (pthread_mutex_trylock(&m_mutex) == 0);
52}
53
54bool CMutex::Lock(void)
55{
56 return (pthread_mutex_lock(&m_mutex) == 0);
57}
58
59void CMutex::Unlock(void)
60{
61 pthread_mutex_unlock(&m_mutex);
62}
63
64static pthread_mutexattr_t g_mutexAttr;
65pthread_mutexattr_t *CMutex::GetMutexAttribute()
66{
67 static bool bAttributeInitialised = false;
68 if (!bAttributeInitialised)
69 {
70 pthread_mutexattr_init(&g_mutexAttr);
71 pthread_mutexattr_settype(&g_mutexAttr, PTHREAD_MUTEX_RECURSIVE);
72 bAttributeInitialised = true;
73 }
74 return &g_mutexAttr;
75}
76
77CCondition::CCondition(void)
78{
79 pthread_cond_init(&m_cond, NULL);
80}
81
82CCondition::~CCondition(void)
83{
84 pthread_cond_broadcast(&m_cond);
85 pthread_cond_destroy(&m_cond);
86}
87
88void CCondition::Broadcast(void)
89{
90 pthread_cond_broadcast(&m_cond);
91}
92
93void CCondition::Signal(void)
94{
95 pthread_cond_signal(&m_cond);
96}
97
98bool CCondition::Wait(IMutex *mutex, uint32_t iTimeout /* = 0 */)
99{
100 bool bReturn(false);
101 sched_yield();
102 CMutex *pmutex = static_cast<CMutex *>(mutex);
103 if (pmutex)
104 {
105 if (iTimeout > 0)
106 {
107 struct timespec abstime;
108 struct timeval now;
109 gettimeofday(&now, NULL);
110 iTimeout += now.tv_usec / 1000;
111 abstime.tv_sec = now.tv_sec + (time_t)(iTimeout / 1000);
112 abstime.tv_nsec = (int32_t)((iTimeout % (uint32_t)1000) * (uint32_t)1000000);
113 bReturn = (pthread_cond_timedwait(&m_cond, &pmutex->m_mutex, &abstime) == 0);
114 }
115 else
116 {
117 bReturn = (pthread_cond_wait(&m_cond, &pmutex->m_mutex) == 0);
118 }
119 }
120 return bReturn;
121}
122
123bool CThread::CreateThread(bool bWait /* = true */)
124{
125 bool bReturn(false);
126 CLockObject lock(m_threadMutex);
127 m_bStop = false;
128 if (!m_bRunning && pthread_create(&m_thread, NULL, (void *(*) (void *))&CThread::ThreadHandler, (void *)this) == 0)
129 {
130 if (bWait)
131 m_threadCondition->Wait(m_threadMutex);
132 bReturn = true;
133 }
134 return bReturn;
135}
136
137bool CThread::StopThread(bool bWaitForExit /* = true */)
138{
139 bool bReturn = IThread::StopThread(bWaitForExit);
140
141 void *retVal;
142 if (bWaitForExit && m_bRunning)
143 bReturn = (pthread_join(m_thread, &retVal) == 0);
144
145 return bReturn;
146}
147
148void *CThread::ThreadHandler(CThread *thread)
149{
150 void *retVal = NULL;
151
152 if (thread)
153 {
154 CLockObject lock(thread->m_threadMutex);
155 thread->m_bRunning = true;
156 lock.Leave();
157 thread->m_threadCondition->Broadcast();
158
159 retVal = thread->Process();
160
161 lock.Lock();
162 thread->m_bRunning = false;
163 lock.Leave();
164 thread->m_threadCondition->Broadcast();
165 }
166
167 return retVal;
168}