CPPMyth
Library to interoperate with MythTV server
All Data Structures Namespaces Functions Variables
os-threads.h
1 #pragma once
2 /*
3  * Copyright (C) 2015 Jean-Luc Barriere
4  *
5  * This library is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published
7  * by the Free Software Foundation; either version 3, or (at your option)
8  * any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this library; see the file COPYING. If not, write to
17  * the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
18  * MA 02110-1301 USA
19  * http://www.gnu.org/copyleft/gpl.html
20  *
21  */
22 
23 #include "../os.h"
24 
25 #if defined(_MSC_VER)
26 #include "../windows/winpthreads.h"
27 #else
28 #include <pthread.h>
29 #endif
30 
31 #ifdef NSROOT
32 namespace NSROOT {
33 #endif
34 namespace OS
35 {
36 
37 #if defined (__WINDOWS__)
38 #define gettimeofday __gettimeofday
39  inline int __gettimeofday(struct timeval *pcur_time, struct timezone *tz)
40  {
41  if (pcur_time == NULL)
42  {
43  SetLastError(EFAULT);
44  return -1;
45  }
46  struct _timeb current;
47  _ftime(&current);
48  pcur_time->tv_sec = (long) current.time;
49  pcur_time->tv_usec = current.millitm * 1000L;
50  if (tz)
51  {
52  tz->tz_minuteswest = current.timezone; /* minutes west of Greenwich */
53  tz->tz_dsttime = current.dstflag; /* type of dst correction */
54  }
55  return 0;
56  }
57 #endif
58 
59  typedef pthread_t thread_t;
60 
61 #define thread_create(a, b, c) __thread_create(a, b, c)
62  inline bool __thread_create(thread_t* thread, void* (*func)(void*), void* arg)
63  {
64  static pthread_attr_t _attr;
65  static bool _init = false;
66  if (!_init)
67  {
68  pthread_attr_init(&_attr);
69  pthread_attr_setdetachstate(&_attr, PTHREAD_CREATE_DETACHED);
70  _init = true;
71  }
72  return pthread_create(thread, &_attr, func, arg) == 0;
73  }
74 
75  typedef pthread_mutex_t mutex_t;
76 
77 #define mutex_init(a) __mutex_init(a)
78  inline bool __mutex_init(mutex_t* mutex)
79  {
80  static pthread_mutexattr_t _attr;
81  static bool _init = false;
82  if (!_init)
83  {
84  pthread_mutexattr_init(&_attr);
85  pthread_mutexattr_settype(&_attr, PTHREAD_MUTEX_RECURSIVE);
86  _init = true;
87  }
88  return pthread_mutex_init(mutex, &_attr) == 0;
89  }
90 
91 #define mutex_lock(a) __mutex_lock(a)
92  inline bool __mutex_lock(mutex_t* mutex) { return pthread_mutex_lock(mutex) == 0; }
93 
94 #define mutex_trylock(a) __mutex_trylock(a)
95  inline bool __mutex_trylock(mutex_t* mutex) { return pthread_mutex_trylock(mutex) == 0; }
96 
97 #define mutex_unlock(a) __mutex_unlock(a)
98  inline void __mutex_unlock(mutex_t* mutex) { pthread_mutex_unlock(mutex); }
99 
100 #define mutex_destroy(a) __mutex_destroy(a)
101  inline void __mutex_destroy(mutex_t* mutex) { pthread_mutex_destroy(mutex); }
102 
103  typedef pthread_cond_t condition_t;
104 
105 #define cond_init(a) __cond_init(a)
106  inline bool __cond_init(condition_t* cond) { return pthread_cond_init(cond, NULL) == 0; }
107 
108 #define cond_signal(a) __cond_signal(a)
109  inline void __cond_signal(condition_t* cond) { pthread_cond_signal(cond); }
110 
111 #define cond_broadcast(a) __cond_broadcast(a)
112  inline void __cond_broadcast(condition_t* cond) { pthread_cond_broadcast(cond); }
113 
114 #define cond_wait(a, b) __cond_wait(a, b)
115  inline bool __cond_wait(condition_t* cond, mutex_t* mutex) { return pthread_cond_wait(cond, mutex) == 0; }
116 
117 #define cond_timedwait(a, b, c) __cond_timedwait(a, b, c)
118  inline bool __cond_timedwait(condition_t* cond, mutex_t* mutex, unsigned millisec)
119  {
120  if (millisec == 0)
121  return cond_wait(cond, mutex);
122 
123  struct timespec time;
124 #if defined(__APPLE__) || defined(__WINDOWS__)
125  struct timeval tv;
126  gettimeofday(&tv, NULL);
127  tv.tv_usec += (millisec % 1000) * 1000;
128  tv.tv_sec += millisec / 1000;
129  time.tv_sec = tv.tv_sec + tv.tv_usec / 1000000;
130  time.tv_nsec = (tv.tv_usec % 1000000) * 1000;
131 #else
132  clock_gettime(CLOCK_REALTIME, &time);
133  time.tv_nsec += (millisec % 1000) * 1000000;
134  time.tv_sec += millisec / 1000 + time.tv_nsec / 1000000000;
135  time.tv_nsec %= 1000000000;
136 #endif
137  return (pthread_cond_timedwait(cond, mutex, &time) == 0);
138  }
139 
140 #define cond_destroy(a) __cond_destroy(a)
141  inline void __cond_destroy(condition_t* cond) { pthread_cond_destroy(cond); }
142 
143 }
144 #ifdef NSROOT
145 }
146 #endif