diff --git a/src/hotplug_libusb.c b/src/hotplug_libusb.c index 46d5506c..82199fe8 100644 --- a/src/hotplug_libusb.c +++ b/src/hotplug_libusb.c @@ -88,6 +88,10 @@ pthread_mutex_t usbNotifierMutex; static pthread_t usbNotifyThread; static int driverSize = -1; static bool AraKiriHotPlug = false; +/** + * the first end is written to when the USB rescan is requested; the second end + * is written to when the rescan thread is about to shut down + */ static int rescan_pipe[] = { -1, -1 }; extern int HPForceReaderPolling; @@ -447,30 +451,6 @@ static void HPRescanUsbBus(void) /* free the libusb allocated list & devices */ libusb_free_device_list(devs, 1); - - if (AraKiriHotPlug) - { - int retval; - - for (i=0; i 0) { Log1(PCSC_LOG_INFO, "Reload serial configuration"); @@ -546,10 +519,32 @@ static void * HPEstablishUSBNotifications(int pipefd[2]) #endif Log1(PCSC_LOG_INFO, "End reload serial configuration"); } - close(rescan_pipe[0]); - rescan_pipe[0] = -1; } + /* Clean up resources before exiting the thread. */ + for (int i=0; i 0) { + /* used for waiting for the initialization completion */ int pipefd[2]; char c; @@ -576,6 +572,13 @@ LONG HPSearchHotPluggables(const char * hpDirPath) return -1; } + /* used for rescan and shutdown events */ + if (pipe(rescan_pipe) == -1) + { + Log2(PCSC_LOG_ERROR, "pipe: %s", strerror(errno)); + return -1; + } + ThreadCreate(&usbNotifyThread, THREAD_ATTR_DETACHED, (PCSCLITE_THREAD_FUNCTION( )) HPEstablishUSBNotifications, pipefd); @@ -599,6 +602,11 @@ LONG HPStopHotPluggables(void) AraKiriHotPlug = true; if (rescan_pipe[1] >= 0) { + char dummy; + /* wait until the rescan thread completes the cleanup */ + read(rescan_pipe[1], &dummy, sizeof(dummy)); + close(rescan_pipe[0]); + rescan_pipe[0] = -1; close(rescan_pipe[1]); rescan_pipe[1] = -1; } diff --git a/src/pcscdaemon.c b/src/pcscdaemon.c index 139c6071..da4500b6 100644 --- a/src/pcscdaemon.c +++ b/src/pcscdaemon.c @@ -114,7 +114,6 @@ static void SVCServiceRunLoop(void) #ifdef USE_USB (void)HPStopHotPluggables(); #endif - (void)SYS_Sleep(1); /* stop all the clients */ ContextsDeinitialize();