mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 11:56:10 +08:00
devif:fix issue about devif_callback being released wrongly,resulting in no access to it
Signed-off-by: wangchen <wangchen41@xiaomi.com>
This commit is contained in:
@@ -274,6 +274,7 @@ struct devif_callback_s
|
|||||||
FAR devif_callback_event_t event;
|
FAR devif_callback_event_t event;
|
||||||
FAR void *priv;
|
FAR void *priv;
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
|
uint8_t free_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
+63
-29
@@ -41,6 +41,13 @@
|
|||||||
#include "netdev/netdev.h"
|
#include "netdev/netdev.h"
|
||||||
#include "devif/devif.h"
|
#include "devif/devif.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Pre-processor Definitions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#define DEVIF_CB_DONT_FREE (1 << 0)
|
||||||
|
#define DEVIF_CB_PEND_FREE (1 << 1)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -90,35 +97,6 @@ static void devif_callback_free(FAR struct net_driver_s *dev,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Remove the callback structure from the device notification list if
|
|
||||||
* it is supposed to be in the device notification list.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (dev != NULL)
|
|
||||||
{
|
|
||||||
/* Find the callback structure in the device event list */
|
|
||||||
|
|
||||||
for (prev = NULL, curr = dev->d_devcb;
|
|
||||||
curr != NULL && curr != cb;
|
|
||||||
prev = curr, curr = curr->nxtdev)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove the structure from the device event list */
|
|
||||||
|
|
||||||
if (curr != NULL)
|
|
||||||
{
|
|
||||||
if (prev)
|
|
||||||
{
|
|
||||||
prev->nxtdev = cb->nxtdev;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dev->d_devcb = cb->nxtdev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove the callback structure from the data notification list if
|
/* Remove the callback structure from the data notification list if
|
||||||
* it is supposed to be in the data notification list.
|
* it is supposed to be in the data notification list.
|
||||||
*/
|
*/
|
||||||
@@ -167,6 +145,48 @@ static void devif_callback_free(FAR struct net_driver_s *dev,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check if the callback structure has DEVIF_CB_DONT_FREE,it indicates
|
||||||
|
* the callback can't be free immediately,setting DEVIF_CB_PEND_FREE
|
||||||
|
* flag with the callback,it indicates the callback will be free
|
||||||
|
* finally
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (cb->free_flags & DEVIF_CB_DONT_FREE)
|
||||||
|
{
|
||||||
|
cb->free_flags |= DEVIF_CB_PEND_FREE;
|
||||||
|
net_unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the callback structure from the device notification list if
|
||||||
|
* it is supposed to be in the device notification list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (dev != NULL)
|
||||||
|
{
|
||||||
|
/* Find the callback structure in the device event list */
|
||||||
|
|
||||||
|
for (prev = NULL, curr = dev->d_devcb;
|
||||||
|
curr != NULL && curr != cb;
|
||||||
|
prev = curr, curr = curr->nxtdev)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the structure from the device event list */
|
||||||
|
|
||||||
|
if (curr != NULL)
|
||||||
|
{
|
||||||
|
if (prev)
|
||||||
|
{
|
||||||
|
prev->nxtdev = cb->nxtdev;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dev->d_devcb = cb->nxtdev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If this is a preallocated or a batch allocated callback store it in
|
/* If this is a preallocated or a batch allocated callback store it in
|
||||||
* the free callbacks list. Else free it.
|
* the free callbacks list. Else free it.
|
||||||
*/
|
*/
|
||||||
@@ -574,12 +594,26 @@ uint16_t devif_dev_event(FAR struct net_driver_s *dev, uint16_t flags)
|
|||||||
|
|
||||||
if (cb->event != NULL && devif_event_trigger(flags, cb->flags))
|
if (cb->event != NULL && devif_event_trigger(flags, cb->flags))
|
||||||
{
|
{
|
||||||
|
cb->free_flags |= DEVIF_CB_DONT_FREE;
|
||||||
|
|
||||||
/* Yes.. perform the callback. Actions perform by the callback
|
/* Yes.. perform the callback. Actions perform by the callback
|
||||||
* may delete the current list entry or add a new list entry to
|
* may delete the current list entry or add a new list entry to
|
||||||
* beginning of the list (which will be ignored on this pass)
|
* beginning of the list (which will be ignored on this pass)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
flags = cb->event(dev, cb->priv, flags);
|
flags = cb->event(dev, cb->priv, flags);
|
||||||
|
cb->free_flags &= ~DEVIF_CB_DONT_FREE;
|
||||||
|
|
||||||
|
/* update the next callback to prevent previously recorded the
|
||||||
|
* next callback from being deleted
|
||||||
|
*/
|
||||||
|
|
||||||
|
next = cb->nxtdev;
|
||||||
|
if ((cb->free_flags & DEVIF_CB_PEND_FREE) != 0)
|
||||||
|
{
|
||||||
|
cb->free_flags &= ~DEVIF_CB_PEND_FREE;
|
||||||
|
devif_callback_free(dev, cb, NULL, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user