1 /*
2   ZynAddSubFX - a software synthesizer
3 
4   ZynSema.h - Semaphore Wrapper
5   Copyright (C) 2016 Mark McCurry
6 
7   This program is free software; you can redistribute it and/or
8   modify it under the terms of the GNU General Public License
9   as published by the Free Software Foundation; either version 2
10   of the License, or (at your option) any later version.
11 */
12 #ifndef ZYNSEMA_H
13 #define ZYNSEMA_H
14 
15 #if defined __APPLE__ || defined WIN32
16 
17 #include <pthread.h>
18 
19 namespace zyn {
20 
21 class ZynSema
22 {
23 public:
ZynSema(void)24     ZynSema (void) : _count (0)
25     {
26     }
27 
~ZynSema(void)28     ~ZynSema (void)
29     {
30         pthread_mutex_destroy (&_mutex);
31         pthread_cond_destroy (&_cond);
32     }
33 
init(int,int v)34     int init (int, int v)
35     {
36         _count = v;
37         return pthread_mutex_init (&_mutex, 0) || pthread_cond_init (&_cond, 0);
38     }
39 
post(void)40     int post (void)
41     {
42         pthread_mutex_lock (&_mutex);
43         if (++_count == 1) pthread_cond_signal (&_cond);
44         pthread_mutex_unlock (&_mutex);
45         return 0;
46     }
47 
wait(void)48     int wait (void)
49     {
50         pthread_mutex_lock (&_mutex);
51         while (_count < 1) pthread_cond_wait (&_cond, &_mutex);
52         --_count;
53         pthread_mutex_unlock (&_mutex);
54         return 0;
55     }
56 
trywait(void)57     int trywait (void)
58     {
59         if (pthread_mutex_trylock (&_mutex)) return -1;
60         if (_count < 1)
61         {
62             pthread_mutex_unlock (&_mutex);
63             return -1;
64         }
65         --_count;
66         pthread_mutex_unlock (&_mutex);
67         return 0;
68     }
69 
getvalue(void)70     int getvalue (void) const
71     {
72         return _count;
73     }
74 
75 
76 private:
77     int              _count;
78     pthread_mutex_t  _mutex;
79     pthread_cond_t   _cond;
80 };
81 
82 }
83 
84 #else // POSIX semaphore
85 
86 #include <semaphore.h>
87 
88 namespace zyn {
89 
90 class ZynSema
91 {
92 public:
ZynSema(void)93     ZynSema (void)
94     {
95     }
~ZynSema(void)96     ~ZynSema (void)
97     {
98         sem_destroy (&_sema);
99     }
init(int s,int v)100     int init (int s, int v)
101     {
102         return sem_init (&_sema, s, v);
103     }
post(void)104     int post (void)
105     {
106         return sem_post (&_sema);
107     }
wait(void)108     int wait (void)
109     {
110         return sem_wait (&_sema);
111     }
trywait(void)112     int trywait (void)
113     {
114         return sem_trywait (&_sema);
115     }
getvalue(void)116     int getvalue(void)
117     {
118         int v = 0;
119         sem_getvalue(&_sema, &v);
120         return v;
121     }
122 
123 private:
124     sem_t _sema;
125 };
126 
127 }
128 
129 #endif // POSIX semapore
130 
131 #endif // ZYNSEMA_H
132