📄 safecoll.cxx
字号:
removalMutex.Signal();
}
BOOL PSafeCollection::DeleteObjectsToBeRemoved()
{
PWaitAndSignal lock(removalMutex);
PINDEX i = 0;
while (i < toBeRemoved.GetSize()) {
if (toBeRemoved[i].SafelyCanBeDeleted()) {
PObject * obj = toBeRemoved.RemoveAt(i);
removalMutex.Signal();
DeleteObject(obj);
removalMutex.Wait();
i = 0; // Restart looking through list
}
else
i++;
}
return toBeRemoved.IsEmpty() && collection->IsEmpty();
}
void PSafeCollection::DeleteObject(PObject * object) const
{
delete object;
}
void PSafeCollection::SetAutoDeleteObjects()
{
if (deleteObjectsTimer.IsRunning())
return;
deleteObjectsTimer.SetNotifier(PCREATE_NOTIFIER(DeleteObjectsTimeout));
deleteObjectsTimer.RunContinuous(1000); // EVery second
}
void PSafeCollection::DeleteObjectsTimeout(PTimer &, INT)
{
DeleteObjectsToBeRemoved();
}
PINDEX PSafeCollection::GetSize() const
{
PWaitAndSignal lock(collectionMutex);
return collection->GetSize();
}
/////////////////////////////////////////////////////////////////////////////
PSafePtrBase::PSafePtrBase(PSafeObject * obj, PSafetyMode mode)
{
collection = NULL;
currentObject = obj;
lockMode = mode;
EnterSafetyMode(WithReference);
}
PSafePtrBase::PSafePtrBase(const PSafeCollection & safeCollection,
PSafetyMode mode,
PINDEX idx)
{
collection = &safeCollection;
currentObject = NULL;
lockMode = mode;
Assign(idx);
}
PSafePtrBase::PSafePtrBase(const PSafeCollection & safeCollection,
PSafetyMode mode,
PSafeObject * obj)
{
collection = &safeCollection;
currentObject = NULL;
lockMode = mode;
Assign(obj);
}
PSafePtrBase::PSafePtrBase(const PSafePtrBase & enumerator)
{
collection = enumerator.collection;
currentObject = enumerator.currentObject;
lockMode = enumerator.lockMode;
EnterSafetyMode(WithReference);
}
PSafePtrBase::~PSafePtrBase()
{
ExitSafetyMode(WithDereference);
}
PObject::Comparison PSafePtrBase::Compare(const PObject & obj) const
{
const PSafePtrBase * other = PDownCast(const PSafePtrBase, &obj);
if (other == NULL)
return GreaterThan;
if (currentObject < other->currentObject)
return LessThan;
if (currentObject > other->currentObject)
return GreaterThan;
return EqualTo;
}
void PSafePtrBase::Assign(const PSafePtrBase & enumerator)
{
if (this == &enumerator)
return;
// lockCount ends up zero after this
ExitSafetyMode(WithDereference);
collection = enumerator.collection;
currentObject = enumerator.currentObject;
lockMode = enumerator.lockMode;
EnterSafetyMode(WithReference);
}
void PSafePtrBase::Assign(const PSafeCollection & safeCollection)
{
// lockCount ends up zero after this
ExitSafetyMode(WithDereference);
collection = &safeCollection;
lockMode = PSafeReadWrite;
Assign((PINDEX)0);
}
void PSafePtrBase::Assign(PSafeObject * newObj)
{
ExitSafetyMode(WithDereference);
currentObject = newObj;
if (newObj == NULL)
return;
if (collection == NULL) {
lockMode = PSafeReference;
if (!EnterSafetyMode(WithReference))
currentObject = NULL;
return;
}
collection->collectionMutex.Wait();
if (collection->collection->GetObjectsIndex(newObj) == P_MAX_INDEX) {
collection->collectionMutex.Signal();
collection = NULL;
lockMode = PSafeReference;
if (!EnterSafetyMode(WithReference))
currentObject = NULL;
}
else {
if (!newObj->SafeReference())
currentObject = NULL;
collection->collectionMutex.Signal();
EnterSafetyMode(AlreadyReferenced);
}
}
void PSafePtrBase::Assign(PINDEX idx)
{
ExitSafetyMode(WithDereference);
currentObject = NULL;
if (collection == NULL)
return;
collection->collectionMutex.Wait();
while (idx < collection->collection->GetSize()) {
currentObject = (PSafeObject *)collection->collection->GetAt(idx);
if (currentObject != NULL) {
if (currentObject->SafeReference())
break;
currentObject = NULL;
}
idx++;
}
collection->collectionMutex.Signal();
EnterSafetyMode(AlreadyReferenced);
}
void PSafePtrBase::Next()
{
if (collection == NULL || currentObject == NULL)
return;
ExitSafetyMode(NoDereference);
collection->collectionMutex.Wait();
PINDEX idx = collection->collection->GetObjectsIndex(currentObject);
currentObject->SafeDereference();
currentObject = NULL;
if (idx != P_MAX_INDEX) {
while (++idx < collection->collection->GetSize()) {
currentObject = (PSafeObject *)collection->collection->GetAt(idx);
if (currentObject != NULL) {
if (currentObject->SafeReference())
break;
currentObject = NULL;
}
}
}
collection->collectionMutex.Signal();
EnterSafetyMode(AlreadyReferenced);
}
void PSafePtrBase::Previous()
{
if (collection == NULL || currentObject == NULL)
return;
ExitSafetyMode(NoDereference);
collection->collectionMutex.Wait();
PINDEX idx = collection->collection->GetObjectsIndex(currentObject);
currentObject->SafeDereference();
currentObject = NULL;
if (idx != P_MAX_INDEX) {
while (idx-- > 0) {
currentObject = (PSafeObject *)collection->collection->GetAt(idx);
if (currentObject != NULL) {
if (currentObject->SafeReference())
break;
currentObject = NULL;
}
}
}
collection->collectionMutex.Signal();
EnterSafetyMode(AlreadyReferenced);
}
BOOL PSafePtrBase::SetSafetyMode(PSafetyMode mode)
{
if (lockMode == mode)
return TRUE;
ExitSafetyMode(NoDereference);
lockMode = mode;
return EnterSafetyMode(AlreadyReferenced);
}
BOOL PSafePtrBase::EnterSafetyMode(EnterSafetyModeOption ref)
{
if (currentObject == NULL)
return FALSE;
if (ref == WithReference && !currentObject->SafeReference()) {
currentObject = NULL;
return FALSE;
}
switch (lockMode) {
case PSafeReadOnly :
if (currentObject->LockReadOnly())
return TRUE;
break;
case PSafeReadWrite :
if (currentObject->LockReadWrite())
return TRUE;
break;
case PSafeReference :
return TRUE;
}
currentObject->SafeDereference();
currentObject = NULL;
return FALSE;
}
void PSafePtrBase::ExitSafetyMode(ExitSafetyModeOption ref)
{
if (currentObject == NULL)
return;
switch (lockMode) {
case PSafeReadOnly :
currentObject->UnlockReadOnly();
break;
case PSafeReadWrite :
currentObject->UnlockReadWrite();
break;
case PSafeReference :
break;
}
if (ref == WithDereference)
currentObject->SafeDereference();
}
// End of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -