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:
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user