00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022 #include <plugin/user_locks/module.h>
00023
00024 #include <boost/thread/locks.hpp>
00025
00026 #include <string>
00027
00028 namespace user_locks {
00029
00030 bool Locks::lock(drizzled::session_id_t id_arg, const user_locks::Key &arg, int64_t wait_for)
00031 {
00032 boost::unique_lock<boost::mutex> scope(mutex);
00033 boost::system_time timeout= boost::get_system_time() + boost::posix_time::seconds(wait_for);
00034
00035 LockMap::iterator iter;
00036 while ((iter= lock_map.find(arg)) != lock_map.end())
00037 {
00038 if (id_arg == iter->second->id)
00039 {
00040
00041 return true;
00042 }
00043 try {
00044 if (wait_for)
00045 {
00046 bool success= release_cond.timed_wait(scope, timeout);
00047
00048 if (not success)
00049 return false;
00050 }
00051 else
00052 {
00053 release_cond.wait(scope);
00054 }
00055 }
00056 catch(boost::thread_interrupted const& error)
00057 {
00058
00059 throw error;
00060 }
00061 }
00062
00063 if (iter == lock_map.end())
00064 {
00065 create_cond.notify_all();
00066 return lock_map.insert(std::make_pair(arg, new Lock(id_arg))).second;
00067 }
00068
00069 return false;
00070 }
00071
00072
00073
00074 void Locks::waitCreate(int64_t wait_for)
00075 {
00076 boost::unique_lock<boost::mutex> scope(mutex);
00077 boost::system_time timeout= boost::get_system_time() + boost::posix_time::seconds(wait_for);
00078
00079 try {
00080 create_cond.timed_wait(scope, timeout);
00081 }
00082 catch(boost::thread_interrupted const& error)
00083 {
00084
00085 throw error;
00086 }
00087 }
00088
00089 bool Locks::lock(drizzled::session_id_t id_arg, const user_locks::Keys &arg)
00090 {
00091 boost::unique_lock<boost::mutex> scope(mutex);
00092 user_locks::Keys created;
00093 bool error= false;
00094
00095 for (user_locks::Keys::const_iterator iter= arg.begin(); iter != arg.end(); iter++)
00096 {
00097 LockMap::iterator record= lock_map.find(*iter);
00098
00099 if (record != lock_map.end())
00100 {
00101 if (id_arg != (*record).second->id)
00102 {
00103
00104 error= true;
00105 break;
00106 }
00107 }
00108 else
00109 {
00110 lock_map.insert(std::make_pair(*iter, new Lock(id_arg)));
00111 created.insert(*iter);
00112 }
00113 }
00114
00115 if (error)
00116 {
00117 for (user_locks::Keys::const_iterator iter= created.begin(); iter != created.end(); iter++)
00118 {
00119 lock_map.erase(*iter);
00120 }
00121
00122 return false;
00123 }
00124
00125 create_cond.notify_all();
00126
00127 return true;
00128 }
00129
00130 bool Locks::isUsed(const user_locks::Key &arg, drizzled::session_id_t &id_arg)
00131 {
00132 boost::unique_lock<boost::mutex> scope(mutex);
00133
00134 LockMap::iterator iter= lock_map.find(arg);
00135
00136 if ( iter == lock_map.end())
00137 return false;
00138
00139 id_arg= iter->second->id;
00140
00141 return true;
00142 }
00143
00144 bool Locks::isFree(const user_locks::Key &arg)
00145 {
00146 boost::unique_lock<boost::mutex> scope(mutex);
00147
00148 LockMap::iterator iter= lock_map.find(arg);
00149
00150 return iter != lock_map.end();
00151 }
00152
00153 void Locks::Copy(LockMap &lock_map_arg)
00154 {
00155 boost::unique_lock<boost::mutex> scope(mutex);
00156 lock_map_arg= lock_map;
00157 }
00158
00159 locks::return_t Locks::release(const user_locks::Key &arg, drizzled::session_id_t &id_arg, bool and_wait)
00160 {
00161 size_t elements= 0;
00162 boost::unique_lock<boost::mutex> scope(mutex);
00163 LockMap::iterator iter= lock_map.find(arg);
00164
00165
00166 if ( iter == lock_map.end())
00167 return locks::NOT_FOUND;
00168
00169 if (iter->second->id == id_arg)
00170 {
00171 elements= lock_map.erase(arg);
00172 assert(elements);
00173
00174 if (elements)
00175 {
00176 release_cond.notify_one();
00177
00178 if (and_wait)
00179 {
00180 bool found= false;
00181 while (not found)
00182 {
00183 assert(boost::this_thread::interruption_enabled());
00184 try {
00185 create_cond.wait(scope);
00186 }
00187 catch(boost::thread_interrupted const& error)
00188 {
00189
00190 throw error;
00191 }
00192 iter= lock_map.find(arg);
00193
00194 if (iter != lock_map.end())
00195 found= true;
00196 }
00197 }
00198
00199 return locks::SUCCESS;
00200 }
00201 }
00202
00203 return locks::NOT_OWNED_BY;
00204 }
00205
00206 }