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 bool timed_out;
00079
00080 try {
00081 timed_out= create_cond.timed_wait(scope, timeout);
00082 }
00083 catch(boost::thread_interrupted const& error)
00084 {
00085
00086 throw error;
00087 }
00088 }
00089
00090 bool Locks::lock(drizzled::session_id_t id_arg, const user_locks::Keys &arg)
00091 {
00092 boost::unique_lock<boost::mutex> scope(mutex);
00093 user_locks::Keys created;
00094 bool error= false;
00095
00096 for (user_locks::Keys::const_iterator iter= arg.begin(); iter != arg.end(); iter++)
00097 {
00098 LockMap::iterator record= lock_map.find(*iter);
00099
00100 if (record != lock_map.end())
00101 {
00102 if (id_arg != (*record).second->id)
00103 {
00104
00105 error= true;
00106 break;
00107 }
00108 }
00109 else
00110 {
00111 lock_map.insert(std::make_pair(*iter, new Lock(id_arg)));
00112 created.insert(*iter);
00113 }
00114 }
00115
00116 if (error)
00117 {
00118 for (user_locks::Keys::const_iterator iter= created.begin(); iter != created.end(); iter++)
00119 {
00120 lock_map.erase(*iter);
00121 }
00122
00123 return false;
00124 }
00125
00126 create_cond.notify_all();
00127
00128 return true;
00129 }
00130
00131 bool Locks::isUsed(const user_locks::Key &arg, drizzled::session_id_t &id_arg)
00132 {
00133 boost::unique_lock<boost::mutex> scope(mutex);
00134
00135 LockMap::iterator iter= lock_map.find(arg);
00136
00137 if ( iter == lock_map.end())
00138 return false;
00139
00140 id_arg= iter->second->id;
00141
00142 return true;
00143 }
00144
00145 bool Locks::isFree(const user_locks::Key &arg)
00146 {
00147 boost::unique_lock<boost::mutex> scope(mutex);
00148
00149 LockMap::iterator iter= lock_map.find(arg);
00150
00151 return iter != lock_map.end();
00152 }
00153
00154 void Locks::Copy(LockMap &lock_map_arg)
00155 {
00156 boost::unique_lock<boost::mutex> scope(mutex);
00157 lock_map_arg= lock_map;
00158 }
00159
00160 locks::return_t Locks::release(const user_locks::Key &arg, drizzled::session_id_t &id_arg, bool and_wait)
00161 {
00162 size_t elements= 0;
00163 boost::unique_lock<boost::mutex> scope(mutex);
00164 LockMap::iterator iter= lock_map.find(arg);
00165
00166
00167 if ( iter == lock_map.end())
00168 return locks::NOT_FOUND;
00169
00170 if (iter->second->id == id_arg)
00171 {
00172 elements= lock_map.erase(arg);
00173 assert(elements);
00174
00175 if (elements)
00176 {
00177 release_cond.notify_one();
00178
00179 if (and_wait)
00180 {
00181 bool found= false;
00182 while (not found)
00183 {
00184 assert(boost::this_thread::interruption_enabled());
00185 try {
00186 create_cond.wait(scope);
00187 }
00188 catch(boost::thread_interrupted const& error)
00189 {
00190
00191 throw error;
00192 }
00193 iter= lock_map.find(arg);
00194
00195 if (iter != lock_map.end())
00196 found= true;
00197 }
00198 }
00199
00200 return locks::SUCCESS;
00201 }
00202 }
00203
00204 return locks::NOT_OWNED_BY;
00205 }
00206
00207 }