RAUL 0.8.0
|
00001 /* This file is part of Raul. 00002 * Copyright (C) 2007-2009 David Robillard <http://drobilla.net> 00003 * 00004 * Raul is free software; you can redistribute it and/or modify it under the 00005 * terms of the GNU General Public License as published by the Free Software 00006 * Foundation; either version 2 of the License, or (at your option) any later 00007 * version. 00008 * 00009 * Raul is distributed in the hope that it will be useful, but WITHOUT ANY 00010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00011 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. 00012 * 00013 * You should have received a copy of the GNU General Public License along 00014 * with this program; if not, write to the Free Software Foundation, Inc., 00015 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00016 */ 00017 00018 #ifndef RAUL_SEMAPHORE_HPP 00019 #define RAUL_SEMAPHORE_HPP 00020 00021 #ifdef __APPLE__ 00022 #include <limits.h> 00023 #include <CoreServices/CoreServices.h> 00024 #else 00025 #include <semaphore.h> 00026 #endif 00027 00028 #include <boost/utility.hpp> 00029 00030 namespace Raul { 00031 00032 00037 class Semaphore : boost::noncopyable { 00038 public: 00039 inline Semaphore(unsigned int initial) { 00040 #ifdef __APPLE__ 00041 MPCreateSemaphore(UINT_MAX, initial, &_sem); 00042 #else 00043 sem_init(&_sem, 0, initial); 00044 #endif 00045 } 00046 00047 inline ~Semaphore() { 00048 #ifdef __APPLE__ 00049 MPDeleteSemaphore(_sem); 00050 #else 00051 sem_destroy(&_sem); 00052 #endif 00053 } 00054 00059 inline void reset(unsigned int initial) { 00060 #ifdef __APPLE__ 00061 MPDeleteSemaphore(_sem); 00062 MPCreateSemaphore(UINT_MAX, initial, &_sem); 00063 #else 00064 sem_destroy(&_sem); 00065 sem_init(&_sem, 0, initial); 00066 #endif 00067 } 00068 00073 inline void post() { 00074 #ifdef __APPLE__ 00075 MPSignalSemaphore(_sem); 00076 #else 00077 sem_post(&_sem); 00078 #endif 00079 } 00080 00085 inline void wait() { 00086 #ifdef __APPLE__ 00087 MPWaitOnSemaphore(_sem, kDurationForever); 00088 #else 00089 /* Note that sem_wait always returns 0 in practice, except in 00090 gdb (at least), where it returns nonzero, so the while is 00091 necessary (and is the correct/safe solution in any case). 00092 */ 00093 while (sem_wait(&_sem) != 0) {} 00094 #endif 00095 } 00096 00103 inline bool try_wait() { 00104 #ifdef __APPLE__ 00105 return MPWaitOnSemaphore(_sem, kDurationImmediate) == noErr; 00106 #else 00107 return (sem_trywait(&_sem) == 0); 00108 #endif 00109 } 00110 00111 private: 00112 #ifdef __APPLE__ 00113 MPSemaphoreID _sem; 00114 #else 00115 sem_t _sem; 00116 #endif 00117 }; 00118 00119 00120 } // namespace Raul 00121 00122 #endif // RAUL_SEMAPHORE_HPP