void igmp_waitmsg(FAR struct igmp_group_s *group, uint8_t msgid) { net_lock_t flags; /* Schedule to send the message */ flags = net_lock(); DEBUGASSERT(!IS_WAITMSG(group->flags)); SET_WAITMSG(group->flags); igmp_schedmsg(group, msgid); /* Then wait for the message to be sent */ while (IS_SCHEDMSG(group->flags)) { /* Wait for the semaphore to be posted */ while (net_lockedwait(&group->sem) != 0) { /* The only error that should occur from net_lockedwait() is if * the wait is awakened by a signal. */ ASSERT(get_errno() == EINTR); } } /* The message has been sent and we are no longer waiting */ CLR_WAITMSG(group->flags); net_unlock(flags); }
static inline void igmp_sched_send(FAR struct net_driver_s *dev, FAR struct igmp_group_s *group) { net_ipaddr_t *dest; /* Check what kind of message we need to send. There are only two * possibilities: */ if (group->msgid == IGMPv2_MEMBERSHIP_REPORT) { dest = &group->grpaddr; nllvdbg("Send IGMPv2_MEMBERSHIP_REPORT, dest=%08x flags=%02x\n", *dest, group->flags); IGMP_STATINCR(g_netstats.igmp.report_sched); SET_LASTREPORT(group->flags); /* Remember we were the last to report */ } else { DEBUGASSERT(group->msgid == IGMP_LEAVE_GROUP); dest = &g_allrouters; nllvdbg("Send IGMP_LEAVE_GROUP, dest=%08x flags=%02x\n", *dest, group->flags); IGMP_STATINCR(g_netstats.igmp.leave_sched); } /* Send the message */ igmp_send(dev, group, dest); /* Indicate that the message has been sent */ CLR_SCHEDMSG(group->flags); group->msgid = 0; /* If there is a thread waiting fore the message to be sent, wake it up */ if (IS_WAITMSG(group->flags)) { nllvdbg("Awakening waiter\n"); sem_post(&group->sem); } }