From 23900a5b4bbc6b32bbc5095f93c02b3b4ad88456 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 17 Aug 2014 14:48:27 -0600 Subject: NSH net monitor: use a seamphore instead of boolean; use sem_timedwait instead of a boolean to communicate --- apps/nshlib/nsh_netinit.c | 78 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 21 deletions(-) (limited to 'apps/nshlib') diff --git a/apps/nshlib/nsh_netinit.c b/apps/nshlib/nsh_netinit.c index d0df779b8..2e49bbbc8 100644 --- a/apps/nshlib/nsh_netinit.c +++ b/apps/nshlib/nsh_netinit.c @@ -54,10 +54,11 @@ #include #include -#include #include #include +#include #include +#include #include #include @@ -77,7 +78,7 @@ #ifdef CONFIG_NET /**************************************************************************** - * Definitions + * Pre-processor Definitions ****************************************************************************/ #if defined(CONFIG_NSH_DRIPADDR) && !defined(CONFIG_NSH_DNSIPADDR) @@ -105,13 +106,21 @@ * signal indicating a change in network status. */ -#define A_REALLY_LONG_TIME (60*60) /* One hour in seconds */ -#define A_SHORT_TIME (2) /* 2 seconds */ +#define LONG_TIME_SEC (60*60) /* One hour in seconds */ +#define SHORT_TIME_SEC (2) /* 2 seconds */ /**************************************************************************** * Private Types ****************************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_NSH_NETINIT_MONITOR +static sem_t g_notify_sem; +#endif + /**************************************************************************** * Private Function Prototypes ****************************************************************************/ @@ -246,11 +255,19 @@ static void nsh_netinit_configure(void) static void nsh_netinit_signal(int signo, FAR siginfo_t *siginfo, FAR void * context) { - volatile bool *event = (volatile bool *)siginfo->si_value.sival_ptr; + int semcount; + int ret; + + /* What is the count on the semaphore? Don't over-post */ + + ret = sem_getvalue(&g_notify_sem, &semcount); + nlldbg("Entry: semcount=%d\n", semcount); + + if (ret == OK && semcount <= 0) + { + sem_post(&g_notify_sem); + } - nlldbg("Entry: event=%p\n", event); - DEBUGASSERT(event); - *event = true; nllvdbg("Exit\n"); } #endif @@ -267,15 +284,20 @@ static void nsh_netinit_signal(int signo, FAR siginfo_t *siginfo, #ifdef CONFIG_NSH_NETINIT_MONITOR static int nsh_netinit_monitor(void) { + struct timespec abstime; + struct timespec reltime; struct ifreq ifr; struct sigaction act; - volatile bool event; bool devup; int ret; int sd; nvdbg("Entry\n"); + /* Initialize the notification semaphore */ + + DEBUGVERIFY(sem_init(&g_notify_sem, 0, 0)); + /* Get a socket descriptor that we can use to communicate with the network * interface driver. */ @@ -310,7 +332,7 @@ static int nsh_netinit_monitor(void) strncpy(ifr.ifr_name, NET_DEVNAME, IFNAMSIZ); ifr.ifr_mii_notify_pid = 0; /* PID=0 means this task */ ifr.ifr_mii_notify_signo = CONFIG_NSH_NETINIT_SIGNO; - ifr.ifr_mii_notify_arg = (FAR void *)&event; + ifr.ifr_mii_notify_arg = NULL; ret = ioctl(sd, SIOCMIINOTIFY, (unsigned long)&ifr); if (ret < 0) @@ -326,10 +348,6 @@ static int nsh_netinit_monitor(void) for (;;) { - /* This should catch any events that occur while we are not listening */ - - event = false; - /* Does the driver think that the link is up or down? */ strncpy(ifr.ifr_name, NET_DEVNAME, IFNAMSIZ); @@ -409,13 +427,15 @@ static int nsh_netinit_monitor(void) * link status again soon. */ - sleep(A_SHORT_TIME); + reltime.tv_sec = SHORT_TIME_SEC; + reltime.tv_nsec = 0; } else { /* The link is still up. Take a long, well-deserved rest */ - sleep(A_REALLY_LONG_TIME); + reltime.tv_sec = LONG_TIME_SEC; + reltime.tv_nsec = 0; } } else @@ -444,14 +464,30 @@ static int nsh_netinit_monitor(void) /* In either case, wait for the short, configurable delay */ - usleep(1000*CONFIG_NSH_NETINIT_RETRYMSEC); + reltime.tv_sec = CONFIG_NSH_NETINIT_RETRYMSEC / 1000; + reltime.tv_nsec = (CONFIG_NSH_NETINIT_RETRYMSEC % 1000) * 1000000; + } + + /* Now wait for either the semaphore to be posted for a timed-out to + * occur. + */ + + sched_lock(); + DEBUGVERIFY(clock_gettime(CLOCK_REALTIME, &abstime)); + + abstime.tv_sec += reltime.tv_sec; + abstime.tv_nsec += reltime.tv_nsec; + if (abstime.tv_nsec > 1000000000) + { + abstime.tv_sec++; + abstime.tv_nsec -= 1000000000; } + + DEBUGVERIFY(sem_timedwait(&g_notify_sem, &abstime)); + sched_unlock(); } - /* TODO: Stop the PHY notifications and remove the signal handler. This - * is important because the 'event' value is on the stack it is about to - * disappear! - */ + /* TODO: Stop the PHY notifications and remove the signal handler. */ errout_with_notification: # warning Missing logic -- cgit v1.2.3