MutexImpl.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2004 Vintela, Inc. All rights reserved.
00003 * Copyright (C) 2005 Novell, Inc. All rights reserved.
00004 *
00005 * Redistribution and use in source and binary forms, with or without
00006 * modification, are permitted provided that the following conditions are met:
00007 *
00008 *  - Redistributions of source code must retain the above copyright notice,
00009 *    this list of conditions and the following disclaimer.
00010 *
00011 *  - Redistributions in binary form must reproduce the above copyright notice,
00012 *    this list of conditions and the following disclaimer in the documentation
00013 *    and/or other materials provided with the distribution.
00014 *
00015 *  - Neither the name of Vintela, Inc., Novell, Inc., nor the names of its
00016 *    contributors may be used to endorse or promote products derived from this
00017 *    software without specific prior written permission.
00018 *
00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00022 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc., Novell, Inc., OR THE 
00023 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00024 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00025 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
00026 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
00027 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
00028 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
00029 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 *******************************************************************************/
00031 
00032 
00038 #include "blocxx/BLOCXX_config.h"
00039 #include "blocxx/MutexImpl.hpp"
00040 #include <cerrno>
00041 #include <cassert>
00042 
00043 namespace BLOCXX_NAMESPACE
00044 {
00045 
00046 namespace MutexImpl
00047 {
00048 
00054 int
00055 createMutex(Mutex_t& handle)
00056 {
00057 #if defined (BLOCXX_USE_PTHREAD)
00058    pthread_mutexattr_t attr;
00059    int res = pthread_mutexattr_init(&attr);
00060    assert(res == 0);
00061    if (res != 0)
00062    {
00063       return -1;
00064    }
00065  
00066 #if defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
00067    res = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
00068    assert(res == 0);
00069    if (res != 0)
00070    {
00071       pthread_mutexattr_destroy(&attr); 
00072       return -1;
00073    }
00074 #endif
00075  
00076    res = pthread_mutex_init(&handle.mutex, &attr);
00077    pthread_mutexattr_destroy(&attr); 
00078    if (res != 0)
00079    {
00080       return -1;
00081    }
00082  
00083 #if !defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
00084    res = pthread_cond_init(&handle.unlocked, 0);
00085    if (res != 0)
00086    {
00087       pthread_mutex_destroy(&handle.mutex);
00088       return -1;
00089    }
00090    
00091    handle.valid_id = false;
00092    handle.count = 0;
00093 #endif
00094    return 0;
00095 #elif defined (BLOCXX_WIN32)
00096    handle = new CRITICAL_SECTION;
00097    assert(handle);
00098    InitializeCriticalSection(handle);
00099    return 0;
00100 #else
00101 #error "port me!"
00102 #endif
00103 }
00113 int
00114 destroyMutex(Mutex_t& handle)
00115 {
00116 #if defined (BLOCXX_USE_PTHREAD)
00117    switch (pthread_mutex_destroy(&handle.mutex))
00118    {
00119       case 0:
00120          break;
00121       case EBUSY:
00122          return -1;
00123          break;
00124       default:
00125          return -2;
00126    }
00127    int res = 0;
00128 #if !defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
00129    res = pthread_cond_destroy(&handle.unlocked);
00130    assert(res == 0);
00131 #endif
00132    return res;
00133 #elif defined(BLOCXX_WIN32)
00134    if(handle)
00135    {
00136       DeleteCriticalSection(handle);
00137       delete handle;
00138       handle = 0;
00139    }
00140    return 0;
00141 #else
00142 #error "port me!"
00143 #endif
00144 }
00153 int
00154 acquireMutex(Mutex_t& handle)
00155 {
00156 #if defined (BLOCXX_USE_PTHREAD)
00157    int res = pthread_mutex_lock(&handle.mutex);
00158    assert(res == 0);
00159  
00160 #if !defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
00161    pthread_t tid = pthread_self();
00162    if (handle.valid_id && pthread_equal(handle.thread_id, tid))
00163    {
00164       ++handle.count;
00165    }
00166    else
00167    {
00168       while (handle.valid_id)
00169       {
00170          res = pthread_cond_wait(&handle.unlocked, &handle.mutex);
00171          assert(res == 0);
00172       }
00173  
00174       handle.thread_id = tid;
00175       handle.valid_id = true;
00176       handle.count = 1;
00177    }
00178  
00179    res = pthread_mutex_unlock(&handle.mutex);
00180    assert(res == 0);
00181 #endif
00182    return res;
00183 #elif defined(BLOCXX_WIN32)
00184    EnterCriticalSection(handle);
00185    return 0;
00186 #else
00187 #error "port me!"
00188 #endif
00189 }
00196 int
00197 releaseMutex(Mutex_t& handle)
00198 {
00199 #if defined (BLOCXX_USE_PTHREAD)
00200 #if defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
00201    int res = pthread_mutex_unlock(&handle.mutex);
00202    assert(res == 0);
00203    return res;
00204 #else
00205    int res = 0;
00206    res = pthread_mutex_lock(&handle.mutex);
00207    assert(res == 0);
00208  
00209    pthread_t tid = pthread_self();
00210    if (handle.valid_id && !pthread_equal(handle.thread_id, tid))
00211    {
00212       res = pthread_mutex_unlock(&handle.mutex);
00213       assert(res == 0);
00214       return -1;
00215    }
00216  
00217    if (--handle.count == 0)
00218    {
00219       assert(handle.valid_id);
00220       handle.valid_id = false;
00221  
00222       res = pthread_cond_signal(&handle.unlocked);
00223       assert(res == 0);
00224    }
00225  
00226    res = pthread_mutex_unlock(&handle.mutex);
00227    assert(res == 0);
00228    return res;
00229 #endif
00230 #elif defined (BLOCXX_WIN32)
00231    LeaveCriticalSection(handle);
00232    return 0;
00233 #else
00234 #error "port me!"
00235 #endif
00236 }
00237 
00238 } // end namespace MutexImpl
00239 } // end namespace BLOCXX_NAMESPACE
00240 

Generated on Fri Jun 16 15:39:08 2006 for blocxx by  doxygen 1.4.6