00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 #ifndef COH_MEMBER_HANDLE_HPP
00017 #define COH_MEMBER_HANDLE_HPP
00018 
00019 #include "coherence/lang/compatibility.hpp"
00020 
00021 #include "coherence/lang/Object.hpp"
00022 #include "coherence/lang/SmartMember.hpp"
00023 #include "coherence/lang/SynchronizedMemberReadBlock.hpp"
00024 #include "coherence/lang/SynchronizedMemberWriteBlock.hpp"
00025 #include "coherence/lang/TypedHandle.hpp"
00026 
00027 #include <ostream>
00028 #include <sstream>
00029 
00030 COH_OPEN_NAMESPACE2(coherence,lang)
00031 
00032 template<class> class MemberView;
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 template<class T>
00056 class MemberHandle
00057     : public SmartMember, public ChainedHandleElement
00058     {
00059     
00060 
00061     public:
00062 
00063 
00064 
00065         typedef T ValueType;
00066 
00067 
00068 
00069 
00070         typedef typename T::Handle ValueHandle;
00071 
00072 
00073 
00074 
00075         typedef typename T::View ValueView;
00076 
00077 
00078 
00079 
00080         typedef ValueHandle GetType;
00081 
00082 
00083 
00084 
00085         typedef ValueView ConstGetType;
00086 
00087 
00088     
00089 
00090     public:
00091 
00092 
00093 
00094 
00095 
00096         MemberHandle(const Object& oGuardian)
00097             : SmartMember(oGuardian), ChainedHandleElement( false),
00098               m_po(NULL)
00099             {
00100             if (oGuardian._isEscaped())
00101                 {
00102                 m_prev = m_next = NULL;
00103                 }
00104             }
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113         MemberHandle(const Object& oGuardian, const ValueHandle& that)
00114             : SmartMember(oGuardian), ChainedHandleElement( false),
00115               m_po(NULL)
00116             {
00117             if (oGuardian._isEscaped())
00118                 {
00119                 m_prev = m_next = NULL;
00120                 }
00121             set(that);
00122             }
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00132 
00133         MemberHandle(const Object& oGuardian, const ValueHandle& that,
00134                 bool fMutable)
00135             : SmartMember(oGuardian), ChainedHandleElement( false),
00136               m_po(NULL)
00137             {
00138             if (oGuardian._isEscaped())
00139                 {
00140                 m_prev = m_next = NULL;
00141                 }
00142             set(that);
00143             m_nMutability = fMutable ? forever_mutable : safe_immutable;
00144             }
00145 
00146 
00147 
00148 
00149         ~MemberHandle()
00150             {
00151             try
00152                 {
00153         const T* cpo = m_po;
00154                 if (cpo && m_fView && m_prev == NULL)
00155                     {
00156                     
00157                     
00158                     cpo->_detach( true);
00159                     }
00160                 else
00161                     {
00162                     
00163                     m_nMutability = inherited;
00164                     set(NULL);
00165                     }
00166                 }
00167             catch (const std::exception& e)
00168                 {
00169                 
00170                 std::cerr << "Error during ~MemberHandle: " << e.what() << std::endl;
00171                 return; 
00172                 }
00173             }
00174 
00175     private:
00176 
00177 
00178 
00179         MemberHandle(const MemberHandle&);
00180 
00181 
00182     
00183 
00184     public:
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192         MemberHandle& operator=(const ValueHandle& that)
00193             {
00194             set(that);
00195             return *this;
00196             }
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206         MemberHandle& operator=(MemberHandle& that)
00207             {
00208             operator=((ValueHandle) that); 
00209             return *this;
00210             }
00211 
00212 
00213 
00214 
00215 
00216 
00217         operator ValueView() const
00218             {
00219             return get();
00220             }
00221 
00222 
00223 
00224 
00225 
00226 
00227         operator ValueHandle()
00228             {
00229             return get();
00230             }
00231 
00232 
00233 
00234 
00235 
00236 
00237         template<class PT>
00238         operator TypedHandle<const PT>() const
00239             {
00240             return get();
00241             }
00242 
00243 
00244 
00245 
00246 
00247 
00248         template<class PT>
00249         operator TypedHandle<PT>()
00250             {
00251             return get();
00252             }
00253 
00254 
00255 
00256 
00257 
00258 
00259 
00260         template<class PT>
00261         operator TypedHolder<PT>() const
00262             {
00263             return get();
00264             }
00265 
00266 
00267 
00268 
00269 
00270 
00271         template<class PT>
00272         operator TypedHolder<PT>()
00273             {
00274             return get();
00275             }
00276 
00277 
00278 
00279 
00280 
00281 
00282         ValueView operator->() const
00283             {
00284             return get();
00285             }
00286 
00287 
00288 
00289 
00290 
00291 
00292         ValueHandle operator->()
00293             {
00294             return get();
00295             }
00296 
00297 
00298 
00299 
00300 
00301 
00302 
00303 
00304         const T& operator*() const
00305             {
00306             return *get();
00307             }
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 
00316         T& operator*()
00317             {
00318             return *get();
00319             }
00320 
00321     private:
00322 
00323 
00324 
00325         MemberHandle<T>& operator=(const MemberHandle<T>&);
00326 
00327 
00328     
00329 
00330     protected:
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339         void set(const TypedHandle<T>& that,
00340                 SynchronizedMemberWriteBlock* pSync = NULL)
00341             {
00342             if (m_prev == NULL)
00343                 {
00344                 setEscaped(that, pSync);
00345                 }
00346             else if (m_nMutability >= forever_immutable)
00347                 {
00348                 coh_throw_illegal_state("attempt to set const MemberHandle");
00349                 }
00350             else
00351                 {
00352                 performAction(link(that));
00353                 m_po = get_pointer(that);
00354                 }
00355             }
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363 
00364 
00365         void setEscaped(const TypedHandle<T>& that,
00366                 SynchronizedMemberWriteBlock* pSync = NULL)
00367             {
00368             const Object& oGuardian = getGuardian();
00369             T*            po        = get_pointer(that);
00370             T*            pDetach   = NULL;
00371             Object*       pAttach   = po == NULL ? NULL : po->_attach( true);
00372 
00373             if (pSync == NULL)
00374                 {
00375                 
00376                 SynchronizedMemberWriteBlock::Guard guard(oGuardian);
00377                 if (m_nMutability >= forever_immutable)
00378                     {
00379                     coh_throw_illegal_state("attempt to set const MemberHandle");
00380                     }
00381                 pDetach = m_po;
00382                 m_po    = NULL == pAttach ? NULL : po;
00383                 }
00384             else
00385                 {
00386                 
00387                 SynchronizedMemberWriteBlock syncWrite(oGuardian, pSync);
00388                 if (m_nMutability >= forever_immutable)
00389                     {
00390                     coh_throw_illegal_state("attempt to set const MemberHandle");
00391                     }
00392                 pDetach = m_po;
00393                 m_po    = NULL == pAttach ? NULL : po;
00394                 }
00395 
00396             if (pDetach)
00397                 {
00398             pDetach->_detach( true);
00399                 }
00400             }
00401 
00402 
00403 
00404 
00405 
00406 
00407 
00408 
00409 
00410         ValueView get(SynchronizedMemberReadBlock* pSync = NULL) const
00411             {
00412             if (m_prev == NULL)
00413                 {
00414                 return getEscaped(pSync);
00415                 }
00416             else
00417                 {
00418                 return TypedHandle<const T>(m_po, *this);
00419                 }
00420             }
00421 
00422 
00423 
00424 
00425 
00426 
00427 
00428 
00429 
00430         ValueView getEscaped(SynchronizedMemberReadBlock* pSync = NULL) const
00431             {
00432             if (pSync != NULL)
00433                 {
00434                 SynchronizedMemberReadBlock syncRead(getGuardian(), pSync);
00435                 
00436                 return ValueView((const T*) m_po);
00437                 }
00438             else if (m_nMutability == safe_immutable)
00439                 {
00440                 
00441                 return ValueView((const T*) m_po);
00442                 }
00443             else
00444                 {
00445                 SynchronizedMemberReadBlock::Guard guard(getGuardian());
00446                 
00447                 return ValueView((const T*) m_po);
00448                 }
00449             }
00450 
00451 
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459         ValueHandle get(SynchronizedMemberReadBlock* pSync = NULL)
00460             {
00461             if (m_prev == NULL)
00462                 {
00463                 return getEscaped(pSync);
00464                 }
00465             else
00466         {
00467                 return TypedHandle<T>(m_po, *this);
00468         }
00469             }
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479         ValueHandle getEscaped(SynchronizedMemberReadBlock* pSync = NULL)
00480             {
00481             const Object& oGuardian = getGuardian();
00482             if (pSync == NULL)
00483                 {
00484                 SynchronizedMemberReadBlock::Guard guard(oGuardian);
00485                 if (m_fView)
00486                     {
00487                     coh_throw_illegal_state(
00488                         "attempt to access handle from const MemberHandle");
00489                     }
00490                 return ValueHandle(m_po); 
00491                 }
00492             else
00493                 {
00494                 SynchronizedMemberReadBlock syncRead(oGuardian, pSync);
00495                 if (m_fView)
00496                     {
00497                     coh_throw_illegal_state(
00498                         "attempt to access handle from const MemberHandle");
00499                     }
00500                 return ValueHandle(m_po); 
00501                 }
00502             }
00503 
00504 
00505 
00506 
00507 
00508 
00509         void performAction(Action nAction) const
00510             {
00511             T* po = m_po;
00512             switch (nAction)
00513                 {
00514                 case action_error:
00515                     coh_throw_illegal_state("corrupted ChainedHandleElement");
00516                 case action_flip:
00517                     if (NULL != po) ((const T*) po)->_attach( false);
00518                     
00519                 case action_detach:
00520                     if (NULL != po)
00521                         {
00522                         if (m_fView)
00523                             {
00524                             ((const T*) po)->_detach( false);
00525                             }
00526                         else
00527                             {
00528                             po->_detach( false);
00529                             }
00530                         }
00531                     
00532                 case action_none:
00533                 default:
00534                     break;
00535                 }
00536             }
00537 
00538     
00539 
00540     protected:
00541 
00542 
00543 
00544 
00545 
00546 
00547         virtual void onConst()
00548             {
00549             bool fEscaped  = m_prev == NULL;
00550             T*   po        = NULL;
00551 
00552             if (fEscaped)
00553                 {
00554                 SynchronizedMemberWriteBlock::Guard guard(getGuardian());
00555                 po = m_po;
00556                 }
00557             else
00558                 {
00559                 po = m_po;
00560                 }
00561 
00562             if (NULL != po)
00563                 {
00564                 
00565                 if (fEscaped)
00566                     {
00567                     ((const T*) po)->_attach( true);
00568                     po->_detach( true);
00569                     }
00570                 else if (scan())
00571                     {
00572                     performAction(action_flip);
00573                     }
00574                 }
00575 
00576             m_fView = true;
00577             SmartMember::onConst();
00578             }
00579 
00580 
00581 
00582 
00583         virtual void onEscape(bool fEscaped) const
00584             {
00585             T* po = m_po;
00586             if (po != NULL)
00587                 {
00588                 if (m_fView)
00589                     {
00590                     const T* cpo = po;
00591                     cpo->_attach(fEscaped);  
00592                     }
00593                 else
00594                     {
00595                     po->_attach(fEscaped);  
00596                     }
00597                 }
00598 
00599             if (fEscaped)
00600                 {
00601                 performAction(unlink());
00602                 m_prev = m_next = NULL;
00603                 }
00604             else
00605                 {
00606                 if (po)
00607                     {
00608                     if (m_fView)
00609                         {
00610                         const T* cpo = po;
00611                         cpo->_detach( true); 
00612                         }
00613                     else
00614                         {
00615                         po->_detach( true); 
00616                         }
00617                     }
00618                 m_prev = m_next = this;
00619                 }
00620 
00621             SmartMember::onEscape(fEscaped);
00622             }
00623 
00624 
00625 
00626 
00627         virtual size64_t retained() const
00628             {
00629             ValueView v = get();
00630             return v == NULL
00631                     ? 0
00632                     : v->sizeOf( true);
00633             }
00634 
00635     
00636 
00637     protected:
00638 
00639 
00640 
00641         T* m_po;
00642 
00643 
00644     
00645 
00646 
00647 
00648 
00649     template<class D, class H> friend D cast(MemberHandle<T>& mh, bool fThrow);
00650 
00651 
00652 
00653 
00654     friend class SynchronizedMemberReadBlock;
00655 
00656 
00657 
00658 
00659     friend class SynchronizedMemberWriteBlock;
00660     };
00661 
00662 
00663 
00664 
00665 
00666 
00667 
00668 
00669 
00670 
00671 
00672 
00673 
00674 template<class T> std::ostream& operator<<(std::ostream& out, const MemberHandle<T>& mh)
00675     {
00676     out << (typename T::View) mh;
00677     return out;
00678     }
00679 
00680 
00681 
00682 
00683 
00684 
00685 template<class T> void clear_handle(MemberHandle<T>& mh)
00686     {
00687     mh = NULL;
00688     }
00689 
00690 
00691 
00692 
00693 
00694 
00695 
00696 
00697 template<class T>
00698 bool is_null(const MemberHandle<T>& mh)
00699     {
00700     return mh == NULL;
00701     }
00702 
00703 
00704 
00705 
00706 
00707 
00708 
00709 
00710 
00711 
00712 
00713 
00714 template<class D, class T>
00715 D cast(MemberHandle<T>& mh, bool fThrow = true)
00716     {
00717     return cast<D>((typename MemberHandle<T>::ValueHandle) mh, fThrow);
00718     }
00719 
00720 
00721 
00722 
00723 
00724 
00725 
00726 
00727 
00728 
00729 
00730 
00731 template<class D, class T>
00732 D cast(const MemberHandle<T>& mh, bool fThrow = true)
00733     {
00734     return cast<D>((typename MemberHandle<T>::ValueView) mh, fThrow);
00735     }
00736 
00737 
00738 
00739 
00740 
00741 
00742 
00743 
00744 template<class D, class T>
00745 bool instanceof(MemberHandle<T>& mh)
00746     {
00747     return NULL != cast<D>(mh, false);
00748     }
00749 
00750 
00751 
00752 
00753 
00754 
00755 
00756 
00757 template<class D, class T>
00758 bool instanceof(const MemberHandle<T>& mh)
00759     {
00760     return NULL != cast<D>(mh, false);
00761     }
00762 
00763 COH_CLOSE_NAMESPACE2
00764 
00765 #endif // COH_MEMBER_HANDLE_HPP