00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
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
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;
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 }