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