1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-13 06:43:42 +00:00

Updated threading rules of ILibLifeTime_Remove()

This commit is contained in:
Bryan Roe
2022-06-27 12:29:51 -07:00
parent af669c1da8
commit ab94c03594
2 changed files with 55 additions and 56 deletions

View File

@@ -917,7 +917,6 @@ struct ILibLifeTime
struct LifeTimeMonitorData *LM; struct LifeTimeMonitorData *LM;
long long NextTriggerTick; long long NextTriggerTick;
void *Reserved;
char *CurrentTriggeredMetaData; char *CurrentTriggeredMetaData;
void *DeleteList; void *DeleteList;
@@ -7767,7 +7766,6 @@ char *ILibLifeTime_GetCurrentTriggeredMetadata(void* LifeTimeMonitorObject)
void ILibLifeTime_Check(void *LifeTimeMonitorObject, fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime) void ILibLifeTime_Check(void *LifeTimeMonitorObject, fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime)
{ {
void *node; void *node;
int removed;
void *EventQueue; void *EventQueue;
long long CurrentTick; long long CurrentTick;
struct LifeTimeMonitorData *EVT, *Temp = NULL; struct LifeTimeMonitorData *EVT, *Temp = NULL;
@@ -7777,6 +7775,16 @@ void ILibLifeTime_Check(void *LifeTimeMonitorObject, fd_set *readset, fd_set *wr
UNREFERENCED_PARAMETER( writeset ); UNREFERENCED_PARAMETER( writeset );
UNREFERENCED_PARAMETER( errorset ); UNREFERENCED_PARAMETER( errorset );
ILibQueue_Lock(LifeTimeMonitor->DeleteList);
while(ILibQueue_GetCount(LifeTimeMonitor->DeleteList) > 0)
{
// This is re-entrant, becuase we are on the microstack thread.
// DeleteList is only locked when called from a different thread.
void *d = ILibQueue_DeQueue(LifeTimeMonitor->DeleteList);
ILibLifeTime_Remove(LifeTimeMonitorObject, d);
}
ILibQueue_UnLock(LifeTimeMonitor->DeleteList);
// //
// Get the current tick count for reference // Get the current tick count for reference
@@ -7796,11 +7804,7 @@ void ILibLifeTime_Check(void *LifeTimeMonitorObject, fd_set *readset, fd_set *wr
// This is an optimization. We are going to create the root of this linked list on the stack instead of the heap. // This is an optimization. We are going to create the root of this linked list on the stack instead of the heap.
EventQueue = ILibMemory_AllocateA(sizeof(ILibLinkedListNode_Root)); EventQueue = ILibMemory_AllocateA(sizeof(ILibLinkedListNode_Root));
ILibLinkedList_Lock(LifeTimeMonitor->Reserved);
ILibLinkedList_Lock(LifeTimeMonitor->ObjectList); ILibLinkedList_Lock(LifeTimeMonitor->ObjectList);
while (ILibQueue_DeQueue(LifeTimeMonitor->Reserved) != NULL);
node = ILibLinkedList_GetNode_Head(LifeTimeMonitor->ObjectList); node = ILibLinkedList_GetNode_Head(LifeTimeMonitor->ObjectList);
while (node != NULL) while (node != NULL)
{ {
@@ -7820,9 +7824,7 @@ void ILibLifeTime_Check(void *LifeTimeMonitorObject, fd_set *readset, fd_set *wr
node = ILibLinkedList_GetNextNode(node); node = ILibLinkedList_GetNextNode(node);
} }
} }
ILibLinkedList_UnLock(LifeTimeMonitor->ObjectList); ILibLinkedList_UnLock(LifeTimeMonitor->ObjectList);
ILibLinkedList_UnLock(LifeTimeMonitor->Reserved);
// //
// Iterate through all the triggers that we need to fire // Iterate through all the triggers that we need to fire
@@ -7830,30 +7832,12 @@ void ILibLifeTime_Check(void *LifeTimeMonitorObject, fd_set *readset, fd_set *wr
node = ILibQueue_DeQueue(EventQueue); node = ILibQueue_DeQueue(EventQueue);
while (node != NULL && ILibMemory_CanaryOK(node)) while (node != NULL && ILibMemory_CanaryOK(node))
{ {
// // Trigger the callback
// Check to see if the item to be fired, is in the remove list.
// If it is, that means we shouldn't fire this item anymore.
//
ILibLinkedList_Lock(LifeTimeMonitor->Reserved);
removed = ILibLinkedList_Remove_ByData(LifeTimeMonitor->Reserved,((struct LifeTimeMonitorData*)node)->data);
ILibLinkedList_UnLock(LifeTimeMonitor->Reserved);
EVT = (struct LifeTimeMonitorData*)node; EVT = (struct LifeTimeMonitorData*)node;
if (removed == 0) LifeTimeMonitor->CurrentTriggeredMetaData = EVT->metadata;
{ EVT->CallbackPtr(EVT->data);
// Trigger the callback LifeTimeMonitor->CurrentTriggeredMetaData = NULL;
LifeTimeMonitor->CurrentTriggeredMetaData = EVT->metadata;
EVT->CallbackPtr(EVT->data);
LifeTimeMonitor->CurrentTriggeredMetaData = NULL;
}
else
{
//
// This item was flagged for removal, so intead of triggering it,
// call the destroy pointer if it exists
//
if (EVT->DestroyPtr != NULL) { EVT->DestroyPtr(EVT->data); }
}
ILibMemory_Free(EVT->metadata); ILibMemory_Free(EVT->metadata);
ILibMemory_Free(EVT); ILibMemory_Free(EVT);
node = ILibQueue_DeQueue(EventQueue); node = ILibQueue_DeQueue(EventQueue);
@@ -7867,31 +7851,56 @@ void ILibLifeTime_Check(void *LifeTimeMonitorObject, fd_set *readset, fd_set *wr
} }
} }
/*! \fn ILibLifeTime_Remove(void *LifeTimeToken, void *data) /*! \fn ILibLifeTime_Remove(void *LifeTimeToken, void *data)
\brief Removes a timed callback from an \a ILibLifeTime module \brief Removes a timed callback from an \a ILibLifeTime module
\param LifeTimeToken The \a ILibLifeTime object to remove the callback from \param LifeTimeToken The \a ILibLifeTime object to remove the callback from
\param data The data object to remove \param data The data object to remove
\return 0 if remove was not deferred, 1 if it was deferred
*/ */
void ILibLifeTime_Remove(void *LifeTimeToken, void *data) int ILibLifeTime_Remove(void *LifeTimeToken, void *data)
{ {
void *node; void *node;
int removed = 0;
struct LifeTimeMonitorData *evt; struct LifeTimeMonitorData *evt;
struct ILibLifeTime *UPnPLifeTime = (struct ILibLifeTime*)LifeTimeToken; struct ILibLifeTime *UPnPLifeTime = (struct ILibLifeTime*)LifeTimeToken;
void *EventQueue; void *EventQueue;
if (UPnPLifeTime == NULL || UPnPLifeTime->ObjectList == NULL) return; if (UPnPLifeTime == NULL || UPnPLifeTime->ObjectList == NULL) return(0);
//// //
//// Check to see if we are on the Microstack Thread, to see if we can simplify this // Check to see if we are on the Microstack Thread, to see if we can simplify this
//// //
//if (ILibIsRunningOnChainThread(UPnPLifeTime->ChainLink.ParentChain) == 0) if (ILibIsRunningOnChainThread(UPnPLifeTime->ChainLink.ParentChain) == 0)
//{ {
// // Not on the right thread, so we need to defer processing to the Microstack Thread int found = 0;
// ILibQueue_Lock(NULL);
// ILibQueue_UnLock(NULL); ILibLinkedList_Lock(UPnPLifeTime->ObjectList);
//} node = ILibLinkedList_GetNode_Head(UPnPLifeTime->ObjectList);
if (node != NULL)
{
while (node != NULL)
{
evt = (struct LifeTimeMonitorData*)ILibLinkedList_GetDataFromNode(node);
if (evt != NULL && ILibMemory_CanaryOK(evt) && evt->data == data)
{
found = 1;
}
node = ILibLinkedList_GetNextNode(node);
}
}
ILibLinkedList_UnLock(UPnPLifeTime->ObjectList);
if (found != 0)
{
// Not on the right thread, so we need to defer processing to the Microstack Thread
ILibQueue_Lock(UPnPLifeTime->DeleteList);
ILibQueue_EnQueue(UPnPLifeTime->DeleteList, data); // It's ok if *data gets deleted before we process it, becuase we aren't dereferencing it, just removing references to it
ILibQueue_UnLock(UPnPLifeTime->DeleteList);
ILibForceUnBlockChain(UPnPLifeTime->ChainLink.ParentChain);
return(1);
}
}
EventQueue = ILibQueue_Create(); EventQueue = ILibQueue_Create();
@@ -7907,7 +7916,6 @@ void ILibLifeTime_Remove(void *LifeTimeToken, void *data)
{ {
ILibQueue_EnQueue(EventQueue, evt); ILibQueue_EnQueue(EventQueue, evt);
node = ILibLinkedList_Remove(node); node = ILibLinkedList_Remove(node);
removed = 1;
} }
else else
{ {
@@ -7915,15 +7923,6 @@ void ILibLifeTime_Remove(void *LifeTimeToken, void *data)
} }
} }
} }
if (removed == 0)
{
//
// The item wasn't in the list, so maybe it is pending to be triggered
//
ILibLinkedList_Lock(UPnPLifeTime->Reserved);
ILibLinkedList_AddTail(UPnPLifeTime->Reserved, data);
ILibLinkedList_UnLock(UPnPLifeTime->Reserved);
}
ILibLinkedList_UnLock(UPnPLifeTime->ObjectList); ILibLinkedList_UnLock(UPnPLifeTime->ObjectList);
// //
@@ -7938,6 +7937,7 @@ void ILibLifeTime_Remove(void *LifeTimeToken, void *data)
evt = (struct LifeTimeMonitorData*)ILibQueue_DeQueue(EventQueue); evt = (struct LifeTimeMonitorData*)ILibQueue_DeQueue(EventQueue);
} }
ILibQueue_Destroy(EventQueue); ILibQueue_Destroy(EventQueue);
return(0);
} }
/*! \fn ILibLifeTime_Flush(void *LifeTimeToken) /*! \fn ILibLifeTime_Flush(void *LifeTimeToken)
@@ -7969,7 +7969,6 @@ void ILibLifeTime_Destroy(void *LifeTimeToken)
struct ILibLifeTime *UPnPLifeTime = (struct ILibLifeTime*)LifeTimeToken; struct ILibLifeTime *UPnPLifeTime = (struct ILibLifeTime*)LifeTimeToken;
ILibLifeTime_Flush(LifeTimeToken); ILibLifeTime_Flush(LifeTimeToken);
ILibLinkedList_Destroy(UPnPLifeTime->ObjectList); ILibLinkedList_Destroy(UPnPLifeTime->ObjectList);
ILibQueue_Destroy(UPnPLifeTime->Reserved);
UPnPLifeTime->ObjectCount = 0; UPnPLifeTime->ObjectCount = 0;
UPnPLifeTime->ObjectList = NULL; UPnPLifeTime->ObjectList = NULL;
} }
@@ -7992,7 +7991,7 @@ void *ILibCreateLifeTime(void *Chain)
RetVal->ChainLink.PreSelectHandler = &ILibLifeTime_Check; RetVal->ChainLink.PreSelectHandler = &ILibLifeTime_Check;
RetVal->ChainLink.DestroyHandler = &ILibLifeTime_Destroy; RetVal->ChainLink.DestroyHandler = &ILibLifeTime_Destroy;
RetVal->ChainLink.ParentChain = Chain; RetVal->ChainLink.ParentChain = Chain;
RetVal->Reserved = ILibQueue_Create(); RetVal->DeleteList = ILibQueue_Create();
ILibAddToChain(Chain, RetVal); ILibAddToChain(Chain, RetVal);
return((void*)RetVal); return((void*)RetVal);

View File

@@ -1399,7 +1399,7 @@ int ILibIsRunningOnChainThread(void* chain);
// //
// Removes all event triggers that contain the specified data object. // Removes all event triggers that contain the specified data object.
// //
void ILibLifeTime_Remove(void *LifeTimeToken, void *data); int ILibLifeTime_Remove(void *LifeTimeToken, void *data);
// //
// Return the expiration time for an event // Return the expiration time for an event