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