mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
sys/net/gnrc/netif: make gnrc_netif_create() blocking
Make gnrc_netif_create() block until the interface is created and registered. This avoids a race condition where after calling gnrc_netif_init_devs() not all interfaces are available yet when iterating through the list of interfaces with gnrc_netif_iter().
This commit is contained in:
parent
8482434bdf
commit
d7c377f400
@ -56,11 +56,18 @@ static void _check_netdev_capabilities(netdev_t *dev);
|
|||||||
static void *_gnrc_netif_thread(void *args);
|
static void *_gnrc_netif_thread(void *args);
|
||||||
static void _event_cb(netdev_t *dev, netdev_event_t event);
|
static void _event_cb(netdev_t *dev, netdev_event_t event);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
gnrc_netif_t *netif;
|
||||||
|
mutex_t init_done;
|
||||||
|
int result;
|
||||||
|
} _netif_ctx_t;
|
||||||
|
|
||||||
int gnrc_netif_create(gnrc_netif_t *netif, char *stack, int stacksize,
|
int gnrc_netif_create(gnrc_netif_t *netif, char *stack, int stacksize,
|
||||||
char priority, const char *name, netdev_t *netdev,
|
char priority, const char *name, netdev_t *netdev,
|
||||||
const gnrc_netif_ops_t *ops)
|
const gnrc_netif_ops_t *ops)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
_netif_ctx_t ctx;
|
||||||
|
|
||||||
if (IS_ACTIVE(DEVELHELP) && gnrc_netif_highlander() && netif_iter(NULL)) {
|
if (IS_ACTIVE(DEVELHELP) && gnrc_netif_highlander() && netif_iter(NULL)) {
|
||||||
LOG_WARNING("gnrc_netif: gnrc_netif_highlander() returned true but "
|
LOG_WARNING("gnrc_netif: gnrc_netif_highlander() returned true but "
|
||||||
@ -81,11 +88,20 @@ int gnrc_netif_create(gnrc_netif_t *netif, char *stack, int stacksize,
|
|||||||
netstats_nb_init(&netif->netif);
|
netstats_nb_init(&netif->netif);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* prepare thread context */
|
||||||
|
ctx.netif = netif;
|
||||||
|
mutex_init(&ctx.init_done);
|
||||||
|
mutex_lock(&ctx.init_done);
|
||||||
|
|
||||||
res = thread_create(stack, stacksize, priority, THREAD_CREATE_STACKTEST,
|
res = thread_create(stack, stacksize, priority, THREAD_CREATE_STACKTEST,
|
||||||
_gnrc_netif_thread, (void *)netif, name);
|
_gnrc_netif_thread, &ctx, name);
|
||||||
(void)res;
|
|
||||||
assert(res > 0);
|
assert(res > 0);
|
||||||
return 0;
|
(void)res;
|
||||||
|
|
||||||
|
/* wait for result of driver init */
|
||||||
|
mutex_lock(&ctx.init_done);
|
||||||
|
|
||||||
|
return ctx.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gnrc_netif_dev_is_6lo(const gnrc_netif_t *netif)
|
bool gnrc_netif_dev_is_6lo(const gnrc_netif_t *netif)
|
||||||
@ -1633,6 +1649,7 @@ static void _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt, bool push_back)
|
|||||||
|
|
||||||
static void *_gnrc_netif_thread(void *args)
|
static void *_gnrc_netif_thread(void *args)
|
||||||
{
|
{
|
||||||
|
_netif_ctx_t *ctx = args;
|
||||||
gnrc_netapi_opt_t *opt;
|
gnrc_netapi_opt_t *opt;
|
||||||
gnrc_netif_t *netif;
|
gnrc_netif_t *netif;
|
||||||
netdev_t *dev;
|
netdev_t *dev;
|
||||||
@ -1641,7 +1658,7 @@ static void *_gnrc_netif_thread(void *args)
|
|||||||
msg_t msg_queue[GNRC_NETIF_MSG_QUEUE_SIZE];
|
msg_t msg_queue[GNRC_NETIF_MSG_QUEUE_SIZE];
|
||||||
|
|
||||||
DEBUG("gnrc_netif: starting thread %i\n", thread_getpid());
|
DEBUG("gnrc_netif: starting thread %i\n", thread_getpid());
|
||||||
netif = args;
|
netif = ctx->netif;
|
||||||
gnrc_netif_acquire(netif);
|
gnrc_netif_acquire(netif);
|
||||||
dev = netif->dev;
|
dev = netif->dev;
|
||||||
netif->pid = thread_getpid();
|
netif->pid = thread_getpid();
|
||||||
@ -1658,9 +1675,11 @@ static void *_gnrc_netif_thread(void *args)
|
|||||||
dev->event_callback = _event_cb;
|
dev->event_callback = _event_cb;
|
||||||
dev->context = netif;
|
dev->context = netif;
|
||||||
/* initialize low-level driver */
|
/* initialize low-level driver */
|
||||||
res = dev->driver->init(dev);
|
ctx->result = dev->driver->init(dev);
|
||||||
if (res < 0) {
|
/* signal that driver init is done */
|
||||||
LOG_ERROR("gnrc_netif: netdev init failed: %d\n", res);
|
mutex_unlock(&ctx->init_done);
|
||||||
|
if (ctx->result < 0) {
|
||||||
|
LOG_ERROR("gnrc_netif: netdev init failed: %d\n", ctx->result);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
netif_register(&netif->netif);
|
netif_register(&netif->netif);
|
||||||
|
Loading…
Reference in New Issue
Block a user