00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <unistd.h>
00019 #include <errno.h>
00020
00021 #include "config.h"
00022
00023 #ifdef HAVE_SYNCH_H
00024 #include <synch.h>
00025 #endif
00026
00027 #include "debug/DebugUtils.h"
00028 #include "debug/Log.h"
00029 #include "Mutex.h"
00030
00031 namespace oasys {
00032
00033 Mutex::Mutex(const char* logbase, lock_type_t type, bool keep_quiet)
00034 : type_(type),
00035 keep_quiet_(keep_quiet)
00036 {
00037 logpathf("%s/lock", logbase);
00038
00039
00040 pthread_mutexattr_t attrs;
00041 if (pthread_mutexattr_init(&attrs) != 0) {
00042 PANIC("fatal error in pthread_mutexattr_init: %s", strerror(errno));
00043 }
00044
00045 int mutex_type;
00046 switch(type_) {
00047 case TYPE_FAST:
00048 mutex_type = PTHREAD_MUTEX_NORMAL;
00049 break;
00050 case TYPE_RECURSIVE:
00051 mutex_type = PTHREAD_MUTEX_RECURSIVE;
00052 break;
00053 default:
00054 NOTREACHED;
00055 break;
00056 }
00057
00058 if (pthread_mutexattr_settype(&attrs, mutex_type) != 0) {
00059 PANIC("fatal error in pthread_mutexattr_settype: %s", strerror(errno));
00060 }
00061
00062 if (pthread_mutex_init(&mutex_, &attrs) != 0) {
00063 PANIC("fatal error in pthread_mutex_init: %s", strerror(errno));
00064 }
00065
00066 if (pthread_mutexattr_destroy(&attrs) != 0) {
00067 PANIC("fatal error in pthread_mutexattr_destroy: %s", strerror(errno));
00068 }
00069 }
00070
00071 Mutex::~Mutex()
00072 {
00073 pthread_mutex_destroy(&mutex_);
00074 if ((keep_quiet_ == false) && (logpath_[0] != 0))
00075 log_debug("destroyed");
00076 }
00077
00078 int
00079 Mutex::lock(const char* lock_user)
00080 {
00081 int err = pthread_mutex_lock(&mutex_);
00082
00083 if (err != 0) {
00084 PANIC("error in pthread_mutex_lock: %s", strerror(errno));
00085 }
00086
00087 ++lock_count_.value;
00088
00089 if ((keep_quiet_ == false) && (logpath_[0] != 0))
00090 log_debug("locked (count %u)", lock_count_.value);
00091
00092 lock_holder_ = Thread::current();
00093 lock_holder_name_ = lock_user;
00094
00095 return err;
00096 }
00097
00098 int
00099 Mutex::unlock()
00100 {
00101 ASSERT(is_locked_by_me());
00102
00103 if (--lock_count_.value == 0) {
00104 lock_holder_ = 0;
00105 lock_holder_name_ = 0;
00106 }
00107
00108 int err = pthread_mutex_unlock(&mutex_);
00109
00110 if (err != 0) {
00111 PANIC("error in pthread_mutex_unlock: %s", strerror(errno));
00112 }
00113
00114 if ((keep_quiet_ == false) && (logpath_[0] != 0))
00115 log_debug("unlocked (count %u)", lock_count_.value);
00116
00117 return err;
00118 }
00119
00120 int
00121 Mutex::try_lock(const char* lock_user)
00122 {
00123 int err = pthread_mutex_trylock(&mutex_);
00124
00125 if (err == EBUSY) {
00126 if ((keep_quiet_ == false) && (logpath_[0] != 0)) {
00127 log_debug("try_lock busy");
00128 }
00129 return EBUSY;
00130 } else if (err != 0) {
00131 PANIC("error in pthread_mutex_trylock: %s", strerror(errno));
00132 }
00133
00134 ++lock_count_.value;
00135 if ((keep_quiet_ == false) && (logpath_[0] != 0))
00136 log_debug("try_lock locked (count %u)", lock_count_.value);
00137 lock_holder_ = Thread::current();
00138 lock_holder_name_ = lock_user;
00139 return err;
00140 }
00141
00142
00143 }