S3FC project page | S3FC home page |
00001 /* 00002 * Stone Three Foundation Class (s3fc) provides a number of utility classes. 00003 * Copyright (C) 2001 by Stone Three Signal Processing (Pty) Ltd. 00004 * 00005 * Authored by Stone Three Signal Processing (Pty) Ltd. 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 * 00021 * Please see the file 'COPYING' in the source root directory. 00022 */ 00023 00033 #include <pthread.h> 00034 #include <s3fc/s3_semaphore.h> 00035 #include <s3fc/s3_exception.h> 00036 00037 #ifndef CONST_OVERRIDE_SEM_T 00038 #define CONST_OVERRIDE_SEM_T(x) const_cast<sem_t*>(x) 00039 #endif 00040 00041 // init semaphore 00042 s3_semaphore::s3_semaphore(int n_value) 00043 { 00044 if ( sem_init(&sem, 0, n_value) != 0 ) 00045 { 00046 throw s3_generic_exception("s3_semaphore::s3_semaphore(int n_value)", 00047 "sem_init() failed - n_value out of range"); 00048 } 00049 } 00050 00051 // destroy semaphore 00052 s3_semaphore::~s3_semaphore() 00053 { 00054 if ( sem_destroy(&sem) != 0 ) 00055 { 00056 throw s3_generic_exception("s3_semaphore::~s3_semaphore()", 00057 "Attempted to destroy semaphore with threads" 00058 " waiting on it."); 00059 } 00060 } 00061 00062 // this should NEVER be called 00063 s3_semaphore::s3_semaphore(const s3_semaphore& src) 00064 { 00065 throw s3_generic_exception("s3_semaphore::s3_semaphore(const s3_semaphore&)", 00066 "Function should *never* be called."); 00067 } 00068 00069 // this should NEVER be called 00070 s3_semaphore& s3_semaphore::operator=(const s3_semaphore& src) 00071 { 00072 throw s3_generic_exception("s3_semaphore::operator=(const s3_semaphore&)", 00073 "Function should *never* be called."); 00074 } 00075 00076 // call sem_wait 00077 void s3_semaphore::wait() const 00078 { 00079 sem_wait(CONST_OVERRIDE_SEM_T(&sem)); 00080 } 00081 00082 // forward to sem_trywait an return true if it succeeds 00083 bool s3_semaphore::try_wait() const 00084 { 00085 bool rv = ( sem_trywait(CONST_OVERRIDE_SEM_T(&sem)) == 0 ); 00086 return rv; 00087 } 00088 00089 // forward to sem_post and throw if it fails 00090 void s3_semaphore::post() const 00091 { 00092 if ( sem_post(CONST_OVERRIDE_SEM_T(&sem)) != 0 ) 00093 { 00094 throw s3_generic_exception("s3_semaphore::post() const", 00095 "Attempted to increment semaphore value" 00096 " past SEM_VALUE_MAX."); 00097 } 00098 } 00099 00100 // forward to sem_getvalue 00101 int s3_semaphore::get_value() const 00102 { 00103 int val = 0; 00104 00105 #if _WIN32 00106 /* 00107 * sem_getvalue is broken on win2k. 00108 * The pthreads WIN32 api use the ReleaseSemaphore call with 00109 * lReleaseCount = 0. However, according the the WIN32 docs, the 00110 * value of lReleaseCount must be larger than zero. 00111 * Therefore, the call works on Win9x but not on WinNT/2k. 00112 * 00113 * 30 May 2002: Jan Pool <jpool@stonethree.com> 00114 */ 00115 00116 /* 00117 * We use sem_trywait() to determine the current count and then 00118 * use sem_post() to put them back. 00119 * 00120 * Very inefficient, but will have to do for now. 00121 */ 00122 while ( sem_trywait( CONST_OVERRIDE_SEM_T(&sem) ) == 0) 00123 { 00124 val++; 00125 } 00126 int cnt = val; 00127 while( cnt-- ) 00128 { 00129 sem_post( CONST_OVERRIDE_SEM_T(&sem) ); 00130 } 00131 #else 00132 sem_getvalue(CONST_OVERRIDE_SEM_T(&sem), &val); 00133 #endif 00134 00135 return val; 00136 } 00137 00138 // while try_wait 00139 void s3_semaphore::flush() const 00140 { 00141 while ( try_wait() ); 00142 }
Send comments to: s3fc@stonethree.com |
|