Mutex.cc

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2004 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 
00039 #include <unistd.h>
00040 #include <errno.h>
00041 
00042 #include "config.h"
00043 
00044 #ifdef HAVE_SYNCH_H
00045 #include <synch.h>
00046 #endif
00047 
00048 #include "debug/DebugUtils.h"
00049 #include "debug/Log.h"
00050 #include "Mutex.h"
00051 
00052 namespace oasys {
00053 
00054 Mutex::Mutex(const char* logbase, lock_type_t type, bool keep_quiet)
00055     : type_(type), 
00056       keep_quiet_(keep_quiet)
00057 {
00058     logpathf("%s/lock", logbase);
00059 
00060     // Set up the type attribute
00061     pthread_mutexattr_t attrs;
00062     if (pthread_mutexattr_init(&attrs) != 0) {
00063         PANIC("fatal error in pthread_mutexattr_init: %s", strerror(errno));
00064     }
00065 
00066     int mutex_type;
00067     switch(type_) {
00068     case TYPE_FAST:
00069         mutex_type = PTHREAD_MUTEX_NORMAL;
00070         break;
00071     case TYPE_RECURSIVE:
00072         mutex_type = PTHREAD_MUTEX_RECURSIVE;
00073         break;
00074     default:
00075         NOTREACHED; // needed to avoid uninitialized variable warning
00076         break;
00077     }
00078 
00079     if (pthread_mutexattr_settype(&attrs, mutex_type) != 0) {
00080         PANIC("fatal error in pthread_mutexattr_settype: %s", strerror(errno));
00081     }
00082 
00083     if (pthread_mutex_init(&mutex_, &attrs) != 0) {
00084         PANIC("fatal error in pthread_mutex_init: %s", strerror(errno));
00085     }
00086 
00087     if (pthread_mutexattr_destroy(&attrs) != 0) {
00088         PANIC("fatal error in pthread_mutexattr_destroy: %s", strerror(errno));
00089     }
00090 }
00091 
00092 Mutex::~Mutex()
00093 {
00094     pthread_mutex_destroy(&mutex_);
00095     if ((keep_quiet_ == false) && (logpath_[0] != 0))
00096         log_debug("destroyed");
00097 }
00098 
00099 int
00100 Mutex::lock(const char* lock_user)
00101 {
00102     int err = pthread_mutex_lock(&mutex_);
00103 
00104     if (err != 0) {
00105         PANIC("error in pthread_mutex_lock: %s", strerror(errno));
00106     }
00107 
00108     ++lock_count_.value;
00109     
00110     if ((keep_quiet_ == false) && (logpath_[0] != 0))
00111         log_debug("locked (count %u)", lock_count_.value);
00112     
00113     lock_holder_      = Thread::current();
00114     lock_holder_name_ = lock_user;
00115     
00116     return err;
00117 }
00118 
00119 int
00120 Mutex::unlock()
00121 {
00122     ASSERT(is_locked_by_me());
00123 
00124     if (--lock_count_.value == 0) {
00125         lock_holder_      = 0;
00126         lock_holder_name_ = 0;
00127     }
00128     
00129     int err = pthread_mutex_unlock(&mutex_);
00130     
00131     if (err != 0) {
00132         PANIC("error in pthread_mutex_unlock: %s", strerror(errno));
00133     }
00134 
00135     if ((keep_quiet_ == false) && (logpath_[0] != 0))
00136         log_debug("unlocked (count %u)", lock_count_.value);
00137     
00138     return err;
00139 }
00140 
00141 int
00142 Mutex::try_lock(const char* lock_user)
00143 {
00144     int err = pthread_mutex_trylock(&mutex_);
00145 
00146     if (err == EBUSY) {
00147         if ((keep_quiet_ == false) && (logpath_[0] != 0)) {
00148             log_debug("try_lock busy");
00149         }
00150         return EBUSY;
00151     } else if (err != 0) {
00152         PANIC("error in pthread_mutex_trylock: %s", strerror(errno));
00153     }
00154 
00155     ++lock_count_.value;
00156     if ((keep_quiet_ == false) && (logpath_[0] != 0))
00157         log_debug("try_lock locked (count %u)", lock_count_.value);
00158     lock_holder_      = Thread::current();
00159     lock_holder_name_ = lock_user;
00160     return err;
00161 }
00162 
00163 
00164 } // namespace oasys

Generated on Fri Dec 22 14:47:59 2006 for DTN Reference Implementation by  doxygen 1.5.1