diff options
| author | 2019-05-25 17:59:40 +0200 | |
|---|---|---|
| committer | 2019-05-25 17:59:40 +0200 | |
| commit | 7430eec6dc7251275559dd4705aaa068af49e5f6 (patch) | |
| tree | b42bd9286b6bde1459a2b6d1732bdb7fb261dc11 | |
| parent | 5304a31704e5ddc9eeefe905f05b5f6938f9c646 (diff) | |
| download | libusbmuxd-7430eec6dc7251275559dd4705aaa068af49e5f6.tar.gz libusbmuxd-7430eec6dc7251275559dd4705aaa068af49e5f6.tar.bz2 | |
inotify: Fix hang when usbmuxd is not running and device monitor is stopped
| -rw-r--r-- | src/libusbmuxd.c | 49 | 
1 files changed, 47 insertions, 2 deletions
| diff --git a/src/libusbmuxd.c b/src/libusbmuxd.c index 40eefea..4553d90 100644 --- a/src/libusbmuxd.c +++ b/src/libusbmuxd.c @@ -73,10 +73,12 @@ extern int _NSGetExecutablePath(char* buf, uint32_t* bufsize);  #ifdef HAVE_INOTIFY  #include <sys/inotify.h> +#include <sys/select.h>  #define EVENT_SIZE  (sizeof (struct inotify_event))  #define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))  #define USBMUXD_DIRNAME "/var/run"  #define USBMUXD_SOCKET_NAME "usbmuxd" +static int use_inotify = 1;  #endif /* HAVE_INOTIFY */  #ifndef HAVE_STPNCPY @@ -193,6 +195,9 @@ static int connect_usbmuxd_socket()  				}  				if (connect_addr && *connect_addr != '\0') {  					int res = socket_connect(connect_addr, port); +#ifdef HAVE_INOTIFY +					use_inotify = 0; +#endif  					free(connect_addr);  					return res;  				} @@ -858,7 +863,30 @@ static int usbmuxd_listen_poll()  }  #ifdef HAVE_INOTIFY -static int use_inotify = 1; +#ifndef HAVE_PSELECT +static int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask) +{ +	int ready; +	struct timeval tv; +	struct timeval *p_timeout; +	sigset_t origmask; + +	if (timeout) { +		tv.tv_sec = timeout->tv_sec; +		tv.tv_usec = timeout->tv_nsec / 1000; +		p_timeout = &tv; +	} else { +		p_timeout = NULL; +	} + +	pthread_sigmask(SIG_SETMASK, sigmask, &origmask); +	ready = select(nfds, readfds, writefds, exceptfds, p_timeout); +	pthread_sigmask(SIG_SETMASK, &origmask, NULL); + +	return ready; +} +#endif +  static int usbmuxd_listen_inotify()  {  	int inot_fd; @@ -889,6 +917,18 @@ static int usbmuxd_listen_inotify()  	}  	while (1) { +		fd_set rfds; +		struct timespec tv = {1, 0}; + +		FD_ZERO(&rfds); +		FD_SET(inot_fd, &rfds); +		int r = pselect(inot_fd+1, &rfds, NULL, NULL, &tv, NULL); +		if (r < 0) { +			break; +		} else if (r == 0) { +			continue; +		} +  		ssize_t len, i;  		char buff[EVENT_BUF_LEN] = {0}; @@ -946,7 +986,9 @@ retry:  #endif  	if (sfd < 0) { -		LIBUSBMUXD_DEBUG(1, "%s: ERROR: usbmuxd was supposed to be running here...\n", __func__); +		if (!cancelling) { +			LIBUSBMUXD_DEBUG(1, "%s: ERROR: usbmuxd was supposed to be running here...\n", __func__); +		}  		return sfd;  	} @@ -1176,6 +1218,9 @@ USBMUXD_API int usbmuxd_events_unsubscribe(usbmuxd_subscription_context_t ctx)  			if (thread_cancel(devmon) < 0) {  				running = 0;  			} +#if defined(HAVE_INOTIFY) && !defined(HAVE_PTHREAD_CANCEL) +			pthread_kill(devmon, SIGINT); +#endif  			res = thread_join(devmon);  			thread_free(devmon);  			devmon = THREAD_T_NULL; | 
