S3FC project page S3FC home page

Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

s3_semaphore.cc

Go to the documentation of this file.
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 SourceForge Logo