📄 safecoll.h
字号:
/**Destroy the thread safe collection. The will delete the collection object provided in the constructor. */ ~PSafeCollection(); //@} /**@name Operations */ //@{ protected: /**Remove an object to the collection. This function removes the object from the collection itself, but does not actually delete the object. It simply moves the object to a list of objects to be garbage collected at a later time. As for Append() full mutual exclusion locking on the collection itself is maintained. */ virtual BOOL SafeRemove( PSafeObject * obj /// Object to remove from collection ); /**Remove an object to the collection. This function removes the object from the collection itself, but does not actually delete the object. It simply moves the object to a list of objects to be garbage collected at a later time. As for Append() full mutual exclusion locking on the collection itself is maintained. */ virtual BOOL SafeRemoveAt( PINDEX idx /// Object index to remove ); public: /**Remove all objects in collection. */ virtual void RemoveAll( BOOL synchronous = FALSE /// Wait till objects are deleted before returning ); /**Disallow the automatic delete any objects that have been removed. Objects are simply removed from the collection and not marked for deletion using PSafeObject::SafeRemove() and DeleteObject(). */ void AllowDeleteObjects( BOOL yes = TRUE /// New value for flag for deleting objects ) { deleteObjects = yes; } /**Disallow the automatic delete any objects that have been removed. Objects are simply removed from the collection and not marked for deletion using PSafeObject::SafeRemove() and DeleteObject(). */ void DisallowDeleteObjects() { deleteObjects = FALSE; } /**Delete any objects that have been removed. Returns TRUE if all objects in the collection have been removed and their pending deletions carried out. */ virtual BOOL DeleteObjectsToBeRemoved(); /**Delete an objects that has been removed. */ virtual void DeleteObject(PObject * object) const; /**Start a timer to automatically call DeleteObjectsToBeRemoved(). */ virtual void SetAutoDeleteObjects(); /**Get the current size of the collection. Note that usefulness of this function is limited as it is merely an instantaneous snapshot of the state of the collection. */ PINDEX GetSize() const; /**Determine if the collection is empty. Note that usefulness of this function is limited as it is merely an instantaneous snapshot of the state of the collection. */ BOOL IsEmpty() const { return GetSize() == 0; } /**Get the mutex for the collection. */ const PMutex & GetMutex() const { return collectionMutex; } //@} protected: void SafeRemoveObject(PSafeObject * obj); PDECLARE_NOTIFIER(PTimer, PSafeCollection, DeleteObjectsTimeout); PCollection * collection; mutable PMutex collectionMutex; BOOL deleteObjects; PList<PSafeObject> toBeRemoved; PMutex removalMutex; PTimer deleteObjectsTimer; friend class PSafePtrBase;};enum PSafetyMode { PSafeReference, PSafeReadOnly, PSafeReadWrite};/** This class defines a base class for thread-safe pointer to an object. This is part of a set of classes to solve the general problem of a collection (eg a PList or PDictionary) of objects that needs to be a made thread safe. Any thread can add, read, write or remove an object with both the object and the database of objects itself kept thread safe. NOTE: the PSafePtr will allow safe and mutexed access to objects but is not thread safe itself! You should not share PSafePtr instances across threads. You can assign a PSafePtr to another instance across a thread boundary provided it is on a reference and no read only or read/write locks are present. See the PSafeObject class for more details. */class PSafePtrBase : public PObject{ PCLASSINFO(PSafePtrBase, PObject); /**@name Construction */ //@{ protected: /**Create a new pointer to a PSafeObject. An optional locking mode may be provided to lock the object for reading or writing and automatically unlock it on destruction. Note that this version is not associated with a collection so the ++ and -- operators will not work. */ PSafePtrBase( PSafeObject * obj = NULL, /// Physical object to point to. PSafetyMode mode = PSafeReference /// Locking mode for the object ); /**Create a new pointer to a PSafeObject. An optional locking mode may be provided to lock the object for reading or writing and automatically unlock it on destruction. The idx'th entry of the collection is pointed to by this object. If the idx is beyond the size of the collection, the pointer is NULL. */ PSafePtrBase( const PSafeCollection & safeCollection, /// Collection pointer will enumerate PSafetyMode mode, /// Locking mode for the object PINDEX idx /// Index into collection to point to ); /**Create a new pointer to a PSafeObject. An optional locking mode may be provided to lock the object for reading or writing and automatically unlock it on destruction. The obj parameter is only set if it contained in the collection, otherwise the pointer is NULL. */ PSafePtrBase( const PSafeCollection & safeCollection, /// Collection pointer will enumerate PSafetyMode mode, /// Locking mode for the object PSafeObject * obj /// Inital object in collection to point to ); /**Copy the pointer to the PSafeObject. This will create a copy of the pointer with the same locking mode and lock on the PSafeObject. It will also increment the reference count on the PSafeObject as well. */ PSafePtrBase( const PSafePtrBase & enumerator /// Pointer to copy ); public: /**Unlock and dereference the PSafeObject this is pointing to. */ ~PSafePtrBase(); //@} /**@name Overrides from class PObject */ //@{ /**Compare the pointers. Note this is not a value comparison and will only return EqualTo if the two PSafePtrBase instances are pointing to the same instance. */ Comparison Compare( const PObject & obj /// Other instance to compare against ) const; //@} /**@name Operations */ //@{ /**Return TRUE if pointer is NULL. */ bool operator!() const { return currentObject == NULL; } /**Get the locking mode used by this pointer. */ PSafetyMode GetSafetyMode() const { return lockMode; } /**Change the locking mode used by this pointer. */ BOOL SetSafetyMode( PSafetyMode mode /// New locking mode ); /**Get the associated collection this pointer may be contained in. */ const PSafeCollection * GetCollection() const { return collection; } //@} void Assign(const PSafePtrBase & ptr); void Assign(const PSafeCollection & safeCollection); void Assign(PSafeObject * obj); void Assign(PINDEX idx); protected: void Next(); void Previous(); enum EnterSafetyModeOption { WithReference, AlreadyReferenced }; BOOL EnterSafetyMode(EnterSafetyModeOption ref); enum ExitSafetyModeOption { WithDereference, NoDereference }; void ExitSafetyMode(ExitSafetyModeOption ref); protected: const PSafeCollection * collection; PSafeObject * currentObject; PSafetyMode lockMode;};/** This class defines a thread-safe enumeration of object in a collection. This is part of a set of classes to solve the general problem of a collection (eg a PList or PDictionary) of objects that needs to be a made thread safe. Any thread can add, read, write or remove an object with both the object and the database of objects itself kept thread safe. There are two modes of safe pointer, one that is enumerating a collection and one that is independent of the collection that the safe object is in. There are some subtle semantics that must be observed in each of these two modes especially when switching from one to the other. NOTE: the PSafePtr will allow safe and mutexed access to objects but is not thread safe itself! You should not share PSafePtr instances across threads. You can assign a PSafePtr to another instance across a thread boundary provided it is on a reference and no read only or read/write locks are present. See the PSafeObject class for more details. Especially in regard to enumeration of collections. */template <class T> class PSafePtr : public PSafePtrBase{ PCLASSINFO(PSafePtr, PSafePtrBase); public: /**@name Construction */ //@{ /**Create a new pointer to a PSafeObject. An optional locking mode may be provided to lock the object for reading or writing and automatically unlock it on destruction. Note that this version is not associated with a collection so the ++ and -- operators will not work. */ PSafePtr( T * obj = NULL, /// Physical object to point to. PSafetyMode mode = PSafeReference /// Locking mode for the object ) : PSafePtrBase(obj, mode) { } /**Create a new pointer to a PSafeObject. An optional locking mode may be provided to lock the object for reading or writing and automatically unlock it on destruction. The idx'th entry of the collection is pointed to by this object. If the idx is beyond the size of the collection, the pointer is NULL. */ PSafePtr( const PSafeCollection & safeCollection, /// Collection pointer will enumerate PSafetyMode mode = PSafeReadWrite, /// Locking mode for the object PINDEX idx = 0 /// Index into collection to point to ) : PSafePtrBase(safeCollection, mode, idx) { } /**Create a new pointer to a PSafeObject. An optional locking mode may be provided to lock the object for reading or writing and automatically unlock it on destruction. The obj parameter is only set if it contained in the collection, otherwise the pointer is NULL. */ PSafePtr( const PSafeCollection & safeCollection, /// Collection pointer will enumerate PSafetyMode mode, /// Locking mode for the object PSafeObject * obj /// Inital object in collection to point to ) : PSafePtrBase(safeCollection, mode, obj) { } /**Copy the pointer to the PSafeObject. This will create a copy of the pointer with the same locking mode and lock on the PSafeObject. It will also increment the reference count on the PSafeObject as well. */ PSafePtr( const PSafePtr & ptr /// Pointer to copy ) : PSafePtrBase(ptr) { } /**Copy the pointer to the PSafeObject. This will create a copy of the pointer with the same locking mode and lock on the PSafeObject. It will also increment the reference count on the PSafeObject as well. */ PSafePtr & operator=(const PSafePtr & ptr) { Assign(ptr); return *this; } /**Start an enumerated PSafeObject. This will create a read/write locked reference to teh first element in the collection. */ PSafePtr & operator=(const PSafeCollection & safeCollection) { Assign(safeCollection); return *this; } /**Set the new pointer to a PSafeObject. This will set the pointer to the new object. The old object pointed to will be unlocked and dereferenced and the new object referenced. If the safe pointer has an associated collection and the new object is in that collection, then the object is set to the same locking mode as the previous pointer value. This, in effect, jumps the enumeration of a collection to the specifed object. If the safe pointer has no associated collection or the object is not in the associated collection, then the object is always only referenced
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -