diff --git a/net/devif/devif.h b/net/devif/devif.h index fc014663331..072deb275af 100644 --- a/net/devif/devif.h +++ b/net/devif/devif.h @@ -260,6 +260,7 @@ typedef CODE uint16_t (*devif_callback_event_t)(FAR struct net_driver_s *dev, struct devif_callback_s { FAR struct devif_callback_s *nxtconn; + FAR struct devif_callback_s *prevconn; FAR struct devif_callback_s *nxtdev; FAR devif_callback_event_t event; FAR void *priv; diff --git a/net/devif/devif_callback.c b/net/devif/devif_callback.c index 69a8b249c14..b2bff67d0c3 100644 --- a/net/devif/devif_callback.c +++ b/net/devif/devif_callback.c @@ -119,41 +119,45 @@ static void devif_callback_free(FAR struct net_driver_s *dev, if (list_head) { - /* Find the callback structure in the connection event list */ - - for (prev = NULL, curr = *list_head; - curr && curr != cb; - prev = curr, curr = curr->nxtconn) - { - } + prev = cb->prevconn; /* Remove the structure from the connection event list */ - DEBUGASSERT(curr); - if (curr) + if (prev) { - if (prev) + /* The item to be removed is not in the head. */ + + prev->nxtconn = cb->nxtconn; + + if (cb->nxtconn) { - /* The found item to be removed is not in the head. */ + /* The item to be removed is not in the tail. */ - prev->nxtconn = cb->nxtconn; + cb->nxtconn->prevconn = prev; } - else + } + else + { + /* The item to be removed is in the head. */ + + *list_head = cb->nxtconn; + + if (cb->nxtconn) { - /* The found item to be removed is in the head. */ + /* There are more items besides the head item. */ - *list_head = cb->nxtconn; + cb->nxtconn->prevconn = NULL; } + } - if (!cb->nxtconn) - { - /* If the tail item is being removed, - * update the tail pointer. - */ + if (!cb->nxtconn) + { + /* If the tail item is being removed, + * update the tail pointer. + */ - DEBUGASSERT(list_tail); - *list_tail = prev; - } + DEBUGASSERT(list_tail); + *list_tail = prev; } } @@ -297,6 +301,7 @@ FAR struct devif_callback_s * if (list_head && list_tail) { ret->nxtconn = NULL; + ret->prevconn = *list_tail; if (*list_tail) {