rendezvous.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "rendezvous.h"
00022
00023 #include <application/windoze_helper.h>
00024 #include <basis/astring.h>
00025 #include <basis/functions.h>
00026 #include <basis/utf_conversion.h>
00027 #include <filesystem/filename.h>
00028
00029 #ifdef __UNIX__
00030 #include <stdio.h>
00031 #include <sys/stat.h>
00032 #include <unistd.h>
00033 #endif
00034
00035 using namespace basis;
00036 using namespace filesystem;
00037
00038 namespace processes {
00039
00040
00041
00042
00043 #undef LOG
00044 #define LOG(tp) printf("%s%s\n", time_stamp::notarize(true).s(), astring(tp).s())
00045
00046
00047
00048
00049
00050 astring general_lock_name(const astring &root_part)
00051 { return root_part + "_app_lock"; }
00052
00053 #ifdef __UNIX__
00054
00055 astring unix_rendez_file(const astring &lock_name)
00056 {
00057 astring clean_name = lock_name;
00058
00059 filename::detooth_filename(clean_name);
00060
00061
00062
00063
00064
00065
00066 astring tmp_dir = "/tmp/rendezvous";
00067
00068 mkdir(tmp_dir.observe(), 0777);
00069 return tmp_dir + "/ren_" + clean_name;
00070 }
00071 #endif
00072
00073 rendezvous::rendezvous(const astring &root_name)
00074 : _handle(NIL),
00075 _locked(false),
00076 _root_name(new astring(root_name))
00077 {
00078 #ifdef DEBUG_RENDEZVOUS
00079 FUNCDEF("constructor");
00080 #endif
00081 astring lock_name = general_lock_name(root_name);
00082 #ifdef __UNIX__
00083 astring real_name = unix_rendez_file(lock_name);
00084 FILE *locking_file = fopen(real_name.s(), "wb");
00085 if (!locking_file) {
00086 #ifdef DEBUG_RENDEZVOUS
00087 LOG(astring("failure to create locking file ") + real_name
00088 + ": " + critical_events::system_error_text(critical_events::system_error()) );
00089 #endif
00090 return;
00091 }
00092
00093 _handle = locking_file;
00094 #endif
00095 #ifdef __WIN32__
00096 _handle = CreateMutex(NIL, false, to_unicode_temp(lock_name));
00097 if (!_handle) return;
00098 #endif
00099 }
00100
00101 rendezvous::~rendezvous()
00102 {
00103 #ifdef DEBUG_RENDEZVOUS
00104 FUNCDEF("destructor");
00105 LOG("okay, into destructor for rendezvous.");
00106 #endif
00107 #ifdef __UNIX__
00108 if (_handle) {
00109 if (_locked) {
00110 int ret = lockf(fileno((FILE *)_handle), F_ULOCK, sizeof(int));
00111 if (ret) {
00112 #ifdef DEBUG_RENDEZVOUS
00113 LOG("failure to get lock on file.");
00114 #endif
00115 }
00116 _locked = false;
00117
00118
00119
00120
00121
00122
00123 }
00124
00125 fclose((FILE *)_handle);
00126 _handle = NIL;
00127 }
00128 #endif
00129 #ifdef __WIN32__
00130 if (_handle) CloseHandle((HANDLE)_handle);
00131 #endif
00132 WHACK(_root_name);
00133 }
00134
00135 void rendezvous::establish_lock() { lock(); }
00136
00137 void rendezvous::repeal_lock() { unlock(); }
00138
00139 bool rendezvous::healthy() const
00140 {
00141 return !!_handle;
00142 }
00143
00144 bool rendezvous::lock(locking_methods how)
00145 {
00146 #ifdef DEBUG_RENDEZVOUS
00147 FUNCDEF("lock");
00148 #endif
00149 if (how == NO_LOCKING) return false;
00150 if (!healthy()) return false;
00151 #ifdef __UNIX__
00152 int command = F_TLOCK;
00153 if (how == ENDLESS_WAIT) command = F_LOCK;
00154 int ret = lockf(fileno((FILE *)_handle), command, sizeof(int));
00155 if (ret) {
00156 #ifdef DEBUG_RENDEZVOUS
00157 LOG("failure to get lock on file.");
00158 #endif
00159 return false;
00160 }
00161 #ifdef DEBUG_RENDEZVOUS
00162 LOG("okay, got lock on shared mem.");
00163 #endif
00164 _locked = true;
00165 return true;
00166 #endif
00167 #ifdef __WIN32__
00168 int timing = 0;
00169 if (how == ENDLESS_WAIT) timing = INFINITE;
00170 int ret = WaitForSingleObject((HANDLE)_handle, timing);
00171 if ( (ret == WAIT_ABANDONED) || (ret == WAIT_TIMEOUT) ) return false;
00172 else if (ret != WAIT_OBJECT_0) {
00173 #ifdef DEBUG_RENDEZVOUS
00174 LOG("got an unanticipated error from waiting for the mutex.");
00175 #endif
00176 return false;
00177 }
00178 _locked = true;
00179 return true;
00180 #endif
00181 return false;
00182 }
00183
00184 void rendezvous::unlock()
00185 {
00186 #ifdef DEBUG_RENDEZVOUS
00187 FUNCDEF("unlock");
00188 #endif
00189 if (!healthy()) return;
00190 if (_locked) {
00191 #ifdef __UNIX__
00192 int ret = lockf(fileno((FILE *)_handle), F_ULOCK, sizeof(int));
00193 if (ret) {
00194 #ifdef DEBUG_RENDEZVOUS
00195 LOG("failure to get lock on file.");
00196 #endif
00197 }
00198 #endif
00199 #ifdef __WIN32__
00200 ReleaseMutex((HANDLE)_handle);
00201 #endif
00202 _locked = false;
00203 } else {
00204 #ifdef DEBUG_RENDEZVOUS
00205 LOG("okay, rendezvous wasn't locked.");
00206 #endif
00207 }
00208 }
00209
00210 }
00211