00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 #ifndef _SK_RT_LOCK_H_
00012 #define _SK_RT_LOCK_H_
00013 
00014 #include <sk/util/Object.h>
00015 
00016 namespace sk {
00017   namespace rt {
00018     class Lock 
00019       : public virtual sk::util::Object
00020     {
00021       public:
00022         virtual void lock() = 0;
00023         virtual bool tryLock() = 0;
00024         virtual void unlock() = 0;
00025         virtual bool isLocked() const = 0;
00026 
00027         template<typename R, typename T, typename TMF> 
00028         R synchronize(T& target, TMF method);
00029 
00030         template<typename T, typename TMF> 
00031         void synchronize(T& target, TMF method);
00032 
00033         template<typename T, typename TMF, typename P> 
00034         void synchronize(T& target, TMF method, P& param);
00035 
00036         template<typename T> 
00037         void synchronize(T& target);
00038 
00039         template<typename T> 
00040         void synchronize(const T& target);
00041 
00042         template<typename T, typename TMF, typename P> 
00043         struct MemberFunctionWithParamInvocator;
00044     };
00045 
00046     typedef void (function_t)();
00047     template<> void Lock::synchronize<function_t>(function_t& function);
00048   }
00049 }
00050 
00051 template<typename R, typename T, typename TMF>
00052 R
00053 sk::rt::Lock::
00054 synchronize(T& target, TMF method)
00055 {
00056   lock();
00057 
00058   try {
00059     R result = (target.*method)();
00060     unlock();
00061     return result;
00062   }
00063   catch(...) {
00064     unlock();
00065     throw;
00066   }
00067 }
00068 
00069 template<typename T, typename TMF>
00070 void
00071 sk::rt::Lock::
00072 synchronize(T& target, TMF method)
00073 {
00074   lock();
00075 
00076   try {
00077     (target.*method)();
00078   }
00079   catch(...) {
00080     unlock();
00081     throw;
00082   }
00083   unlock();
00084 }
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 template<typename T, typename TMF, typename P>
00093 void
00094 sk::rt::Lock::
00095 synchronize(T& target, TMF method, P& param)
00096 {
00097   lock();
00098 
00099   try {
00100     (target.*method)(param);
00101   }
00102   catch(...) {
00103     unlock();
00104     throw;
00105   }
00106   unlock();
00107 }
00108 
00109 #if 0 
00110 
00111 template<typename T, typename TMF, typename P>
00112 struct sk::rt::Lock::MemberFunctionWithParamInvocator {
00113   MemberFunctionWithParamInvocator(T& target, TMF method, P& param)
00114     : _target(target), _method(method), _param(param) {}
00115 
00116   void invoke() {
00117     (_target.*_method)(_param);
00118   }
00119   T& _target;
00120   TMF _method;
00121   P& _param;
00122 };
00123 
00124 template<typename T, typename TMF, typename P>
00125 void
00126 sk::rt::Lock::
00127 synchronize(T& target, TMF method, P& param)
00128 {
00129   MemberFunctionWithParamInvocator<T, TMF, P> invocator(target, method, param);
00130   synchronize(invocator, &MemberFunctionWithParamInvocator<T, TMF, P>::invoke);
00131 }
00132 
00133 #endif
00134 
00135 template<typename T>
00136 void 
00137 sk::rt::Lock::
00138 synchronize(T& target)
00139 {
00140   synchronize(target, &T::operator());
00141 }
00142 
00143 template<typename T>
00144 void 
00145 sk::rt::Lock::
00146 synchronize(const T& target)
00147 {
00148   synchronize(target, &T::operator());
00149 }
00150 
00151 #endif