Smart pointers for Android Analytics

Source: Internet
Author: User
Tags sprintf stack trace

    1. A smart pointer is a wrapper class that has a pointer to a real class object
    2. Reference count smart pointer, which is the reference count that should be held by the real class, not the wrapper class (smart pointer)
    3. For convenience, the reference count is implemented separately in a class so that all classes that inherit it have counters
---------------------------------------------------------------------------template <typename T>class sp{    Public:inline sp (): m_ptr (0) {} sp (t* other);    SP (const sp<t>& Other);    Template<typename u> sp (u* Other);    Template<typename u> SP (const sp<u>& Other);    ~SP ();    Assignment sp& operator = (t* other);    sp& operator = (const sp<t>& other);    Template<typename u> sp& operator = (const sp<u>& other);    Template<typename u> sp& operator = (u* other);    void Force_set (t* other);    Reset void Clear (); Accessors inline t& operator* () const {return *m_ptr;}  Override operator to get the real object inline t* operator-> () const {return m_ptr;    } inline t* get () const {return m_ptr;}        Operators COMPARE (= =) COMPARE (! =) COMPARE (>) COMPARE (<) COMPARE (<=) COMPARE (>=) Private: Template<typename y> FRIend class SP;    Template<typename y> Friend class WP;    void Set_pointer (t* ptr); t* m_ptr;//Pointer to a real class object};

---------------------------------------------------------------------------class refbase//All classes that inherit the class hold a counter {            Public:void Incstrong (const void* ID) const;                void Decstrong (const void* ID) const;            void Forceincstrong (const void* ID) const; //!            Debugging Only:get current strong ref count.    int32_t getstrongcount () const;                Class weakref_type//This corresponds to the counter {public:refbase* refbase () const;        void Incweak (const void* ID);                void Decweak (const void* ID);        Acquires a strong reference if there is already one.                BOOL Attemptincstrong (const void* ID);        Acquires a weak reference if there is already one. This is not always safe.        See ProcessState.cpp and BpBinder.cpp//for proper use.        BOOL Attemptincweak (const void* ID); //! DebuggING Only:get Current Weak ref count.        int32_t getweakcount () const; //!        Debugging Only:print references held on object.                void Printrefs () const;    void Trackme (bool enable, bool retain);                };                        weakref_type* createweak (const void* ID) const;            weakref_type* getweakrefs () const; //!    Debugging Only:print references held on object.            inline void Printrefs () const {getweakrefs ()->printrefs ();} //!    debugging only:enable tracking of object.     inline void Trackme (bool enable, bool retain) {Getweakrefs ()->trackme (enable, retain);    } typedef refbase Basetype;protected:refbase ();    Virtual ~refbase (); //! Flags for Extendobjectlifetime () enum {Object_lifetime_strong = 0x0000, Object_lifetime_weak = 0x000 1, Object_lifetime_mask =0X0001};                void Extendobjectlifetime (int32_t mode); //!        Flags for onincstrongattempted () enum {first_inc_strong = 0x0001};    virtual void onfirstref ();    virtual void Onlaststrongref (const void* ID);    virtual bool Onincstrongattempted (uint32_t flags, const void* ID);    virtual void Onlastweakref (const void* ID);p Rivate:friend class Referencemover;     static void Movereferences (void* D, void const* S, size_t N, const referenceconverterbase& caster);p rivate:    Friend class Weakref_type;                                Class Weakref_impl;            Refbase (const refbase& o);        refbase& operator= (const refbase& o); weakref_impl* const mrefs;};



---------------------------------------------------------------------------class Refbase::weakref_impl:public refbase::weakref_type//Reference counter Implementation class {Public:volatile int32_t mstrong;//Strong reference volatile int32_t mweak;//if reference Refbas    e* Const mbase; Volatile int32_t mflags; #if!        Debug_refs Weakref_impl (refbase* base): Mstrong (Initial_strong_value), Mweak (0), Mbase (base)    , Mflags (0) {} void Addstrongref (const void*/*id*/) {} void Removestrongref (const void*/*id*/) {}    void Renamestrongrefid (const void*/*old_id*/, const void*/*new_id*/) {} void Addweakref (const void*/*id*/) {}    void Removeweakref (const void*/*id*/) {} void Renameweakrefid (const void*/*old_id*/, const void*/*new_id*/) {} void Printrefs () const {} void Trackme (bool, bool) {} #else Weakref_impl (refbase* base): Mstrong (Initial_st Rong_value), Mweak (0), Mbase (base), Mflags (0), Mstrongrefs (NULL)       , Mweakrefs (NULL), mtrackenabled (!! Debug_refs_enabled_by_default), Mretain (false) {} ~weakref_impl () {bool DumpStack = False        ; if (!mretain && mstrongrefs! = NULL) {DumpStack = true; #if debug_refs_fatal_sanity_checks L Og_always_fatal ("Strong references remain!");            #else Aloge ("Strong references remain:"); #endif ref_entry* refs = mstrongrefs; while (refs) {Char inc = Refs->ref >= 0?                ' + ': '-'; ALOGD ("\t%c ID%p (ref%d):", Inc, Refs->id, Refs->ref); #if debug_refs_callstack_enabled Refs->sta            Ck.dump (); #endif refs = refs->next; }} if (!mretain && mweakrefs! = NULL) {DumpStack = true; #if Debug_refs_fatal_sanity_che CKS log_always_fatal ("Weak references remain:"), #else aloge ("Weak references remain!"); #endif ref_entry* refs = mweakrefs; while (refs) {Char inc = Refs->ref >= 0?                ' + ': '-'; ALOGD ("\t%c ID%p (ref%d):", Inc, Refs->id, Refs->ref); #if debug_refs_callstack_enabled Refs->sta            Ck.dump (); #endif refs = refs->next;            }} if (DumpStack) {aloge ("above errors at:");            CallStack stack;            Stack.update ();        Stack.dump ();  }} void Addstrongref (const void* ID) {//alogd_if (mtrackenabled,//"addstrongref:refbase=%p,        Id=%p ", mbase, id);    ADDREF (&mstrongrefs, ID, mstrong); } void Removestrongref (const void* ID) {//alogd_if (mtrackenabled,//"removestrongref:refbase=%p        , id=%p ", mbase, id);        if (!mretain) {removeref (&mstrongrefs, id);        } else {AddRef (&mstrongrefs, ID,-mstrong); }} void Renamestrongrefid (const void* old_id, const void* new_id) {//alogd_if (mtrackenabled,//"renamestrongrefid:refbase=%p, oid=%p, nid=%p",/        /Mbase, old_id, new_id);    Renamerefsid (Mstrongrefs, old_id, new_id);    } void Addweakref (const void* ID) {ADDREF (&mweakrefs, ID, mweak);        } void Removeweakref (const void* ID) {if (!mretain) {removeref (&mweakrefs, id);        } else {AddRef (&mweakrefs, ID,-mweak);    }} void Renameweakrefid (const void* old_id, const void* new_id) {renamerefsid (mweakrefs, old_id, new_id);        } void Trackme (bool track, bool retain) {mtrackenabled = track;    Mretain = retain;        } void Printrefs () const {STRING8 text;            {Mutex::autolock _l (Mmutex);            Char buf[128];            sprintf (BUF, "strong references on Refbase%p (weakref_type%p): \ n", mbase, this);            Text.append (BUF); Printrefslocked (&text, Mstrongrefs);            sprintf (buf, "Weak references on Refbase%p (weakref_type%p): \ n", mbase, this);            Text.append (BUF);        Printrefslocked (&text, mweakrefs);            } {char name[100];            snprintf (name, +, "/data/%p.stack", this); int rc = open (name, O_RDWR | O_creat |            O_append);                if (RC >= 0) {write (RC, text.string (), text.length ());                Close (RC);            ALOGD ("STACK TRACE for%p saved in%s", this, name);         } else Aloge ("FAILED to PRINT STACK TRACE for%p in%s:%s", this, name, Strerror (errno));        }}private:struct ref_entry {ref_entry* next;    const void* ID; #if debug_refs_callstack_enabled callstack stack; #endif int32_t ref;    }; void AddRef (ref_entry** refs, const void* ID, int32_t mref) {if (mtrackenabled) {Automutex _l (mmute            x); ref_entry* ref = new REF_ENTRY  Reference count at the time of the snapshot, but before the//update.            Positive value means we increment, negative--we//decrement the reference count.            Ref->ref = mref; Ref->id = ID; #if debug_refs_callstack_enabled ref->stack.update (2); #endif ref->next = *refs            ;        *refs = ref; }} void Removeref (ref_entry** refs, const void* ID) {if (mtrackenabled) {Automutex _l (Mmutex                        );            ref_entry* const HEAD = *refs;            ref_entry* ref = head;                    while (ref! = NULL) {if (Ref->id = = id) {*refs = ref->next;                    Delete ref;                Return                } refs = &ref->next;            ref = *refs;                    } #if debug_refs_fatal_sanity_checks log_always_fatal ("refbase:removing ID%p on refbase%p" "(WeakRef_type%p) that doesn ' t exist! ", ID, mbase, this); #endif aloge (" refbase:removing-ID%p on            Refbase%p "" (Weakref_type%p) that doesn ' t exist! ', ID, mbase, this);            ref = head; while (ref) {Char inc = Ref->ref >= 0?                ' + ': '-';                ALOGD ("\t%c ID%p (ref%d):", Inc, Ref->id, Ref->ref);            ref = ref->next;            } callstack Stack;            Stack.update ();        Stack.dump ();            }} void Renamerefsid (ref_entry* r, Const void* old_id, const void* new_id) {if (mtrackenabled) {            Automutex _l (Mmutex);            ref_entry* ref = R;                while (ref! = NULL) {if (Ref->id = = old_id) {ref->id = new_id;            } ref = ref->next;     }}} void Printrefslocked (string8* out, const ref_entry* refs) const {   Char buf[128]; while (refs) {Char inc = Refs->ref >= 0?            ' + ': '-';            sprintf (buf, "\t%c ID%p (ref%d): \ n", Inc, Refs->id, Refs->ref);            Out->append (BUF), #if debug_refs_callstack_enabled out->append (refs->stack.tostring ("\t\t")); #else        Out->append ("\t\t (call stacks Disabled)"); #endif refs = refs->next;    }} mutable Mutex Mmutex;    ref_entry* mstrongrefs;    ref_entry* mweakrefs;    BOOL mtrackenabled; Collect stack traces on AddRef and removeref, instead of deleting the stack references//on removeref that match th    e address ones. bool Mretain; #endif};

  

Summary:

    1. Typically, smart pointers are divided into SP and WP
    2. The parent class of the target object is refbase--this base class provides a reference counter for the Weakref_impl type that can be controlled at the same time as the strength reference

Smart pointers for Android Analytics

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.