From e855c861acde634662957131bbfb367260f8daf0 Mon Sep 17 00:00:00 2001 From: Hector Martin Date: Sat, 10 Oct 2009 16:01:26 +0200 Subject: Disable polling in udev mode, use udev to signal device discovery --- daemon/main.c | 58 ++++++++++++++++++++++++++++++++++++++++-------------- daemon/usb-linux.c | 12 ++++++++++- daemon/usb.h | 2 ++ 3 files changed, 56 insertions(+), 16 deletions(-) diff --git a/daemon/main.c b/daemon/main.c index ef98e75..893f26d 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -48,6 +48,7 @@ static const char *socket_path = "/var/run/usbmuxd"; static const char *lockfile = "/var/run/usbmuxd.pid"; int should_exit; +int should_discover; static int verbose = 0; static int foreground = 0; @@ -96,21 +97,26 @@ int create_socket(void) { void handle_signal(int sig) { - if (sig != SIGUSR1) { + if (sig != SIGUSR1 && sig != SIGUSR2) { usbmuxd_log(LL_NOTICE,"Caught signal %d, exiting", sig); should_exit = 1; } else { if(opt_udev) { - usbmuxd_log(LL_INFO, "Caught SIGUSR1, checking if we can terminate (no more devices attached)..."); - if (device_get_count() > 0) { - // we can't quit, there are still devices attached. - usbmuxd_log(LL_NOTICE, "Refusing to terminate, there are still devices attached. Kill me with signal 15 (TERM) to force quit."); - } else { - // it's safe to quit - should_exit = 1; + if (sig == SIGUSR1) { + usbmuxd_log(LL_INFO, "Caught SIGUSR1, checking if we can terminate (no more devices attached)..."); + if (device_get_count() > 0) { + // we can't quit, there are still devices attached. + usbmuxd_log(LL_NOTICE, "Refusing to terminate, there are still devices attached. Kill me with signal 15 (TERM) to force quit."); + } else { + // it's safe to quit + should_exit = 1; + } + } else if (sig == SIGUSR2) { + usbmuxd_log(LL_INFO, "Caught SIGUSR2, scheduling device discovery"); + should_discover = 1; } } else { - usbmuxd_log(LL_INFO, "Caught SIGUSR1 but we weren't started in --udev mode, ignoring"); + usbmuxd_log(LL_INFO, "Caught SIGUSR1/2 but we weren't started in --udev mode, ignoring"); } } } @@ -124,6 +130,7 @@ void set_signal_handlers(void) sigaction(SIGQUIT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGUSR1, &sa, NULL); + sigaction(SIGUSR2, &sa, NULL); } int main_loop(int listenfd) @@ -150,10 +157,17 @@ int main_loop(int listenfd) usbmuxd_log(LL_FLOOD, "poll() returned %d", cnt); if(cnt == -1) { - if(errno == EINTR && should_exit) { - usbmuxd_log(LL_INFO, "event processing interrupted"); - fdlist_free(&pollfds); - return 0; + if(errno == EINTR) { + if(should_exit) { + usbmuxd_log(LL_INFO, "event processing interrupted"); + fdlist_free(&pollfds); + return 0; + } + if(should_discover) { + should_discover = 0; + usbmuxd_log(LL_INFO, "device discovery triggered by udev"); + usb_discover(); + } } } else if(cnt == 0) { if(usb_process() < 0) { @@ -391,6 +405,7 @@ int main(int argc, char *argv[]) usbmuxd_log(LL_NOTICE, "usbmux v%s starting up", USBMUXD_VERSION); should_exit = 0; + should_discover = 0; set_signal_handlers(); @@ -425,8 +440,18 @@ int main(int argc, char *argv[]) usbmuxd_log(LL_ERROR, "Another instance is already running (pid %d). exiting.", lock.l_pid); res = -1; } else { - usbmuxd_log(LL_NOTICE, "Another instance is already running (pid %d). exiting.", lock.l_pid); - res = 0; + usbmuxd_log(LL_NOTICE, "Another instance is already running (pid %d). Telling it to check for devices.", lock.l_pid); + if (lock.l_pid && !kill(lock.l_pid, 0)) { + usbmuxd_log(LL_NOTICE, "Sending signal SIGUSR2 to instance with pid %d", lock.l_pid); + res = 0; + if (kill(lock.l_pid, SIGUSR2) < 0) { + usbmuxd_log(LL_FATAL, "Could not deliver SIGUSR2 to pid %d", lock.l_pid); + res = -1; + } + } else { + usbmuxd_log(LL_ERROR, "Could not determine pid of the other running instance!"); + res = -1; + } } goto terminate; } @@ -523,6 +548,9 @@ int main(int argc, char *argv[]) if((res = notify_parent(0)) < 0) goto terminate; + if(opt_udev) + usb_autodiscover(0); // discovery triggered by udev + res = main_loop(listenfd); if(res < 0) usbmuxd_log(LL_FATAL, "main_loop failed"); diff --git a/daemon/usb-linux.c b/daemon/usb-linux.c index 0edc557..1f70f46 100644 --- a/daemon/usb-linux.c +++ b/daemon/usb-linux.c @@ -53,6 +53,7 @@ static struct collection device_list; static struct timeval next_dev_poll_time; static int devlist_failures; +static int device_polling; static void usb_disconnect(struct usb_device *dev) { @@ -214,7 +215,7 @@ static int start_rx(struct usb_device *dev) return 0; } -static int usb_discover(void) +int usb_discover(void) { int cnt, i, res; int valid_count = 0; @@ -393,10 +394,18 @@ void usb_get_fds(struct fdlist *list) free(usbfds); } +void usb_autodiscover(int enable) +{ + usbmuxd_log(LL_DEBUG, "usb polling enable: %d", enable); + device_polling = enable; +} + static int dev_poll_remain_ms(void) { int msecs; struct timeval tv; + if(!device_polling) + return 100000; // devices will never be polled if this is > 0 gettimeofday(&tv, NULL); msecs = (next_dev_poll_time.tv_sec - tv.tv_sec) * 1000; msecs += (next_dev_poll_time.tv_usec - tv.tv_usec) / 1000; @@ -493,6 +502,7 @@ int usb_init(void) usbmuxd_log(LL_DEBUG, "usb_init for linux / libusb 1.0"); devlist_failures = 0; + device_polling = 1; res = libusb_init(NULL); //libusb_set_debug(NULL, 3); if(res != 0) { diff --git a/daemon/usb.h b/daemon/usb.h index 7e20dce..9b2cb1a 100644 --- a/daemon/usb.h +++ b/daemon/usb.h @@ -57,6 +57,8 @@ uint16_t usb_get_pid(struct usb_device *dev); void usb_get_fds(struct fdlist *list); int usb_get_timeout(void); int usb_send(struct usb_device *dev, const unsigned char *buf, int length); +int usb_discover(void); +void usb_autodiscover(int enable); int usb_process(void); int usb_process_timeout(int msec); -- cgit v1.1-32-gdbae