mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	pa_poll(): Simplify detection of invalid fds in select() emulation mode
For systems which have a fcntl() implementation, we can simplify the code which determines whether a file selector is valid in pa_poll(). The old code, which is harder to read and more expensive, stays around for all platforms we need to emulate poll() for using select(), and which don't provide fcntl(). IOW, for Windows. On Mac OS X, however, the detection for bad fds via more select() calls doesn't work, resulting in hung main loops, so the patch fixes a real bug there.
This commit is contained in:
		
							parent
							
								
									a2581e6688
								
							
						
					
					
						commit
						a44092d39d
					
				
					 1 changed files with 27 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -40,6 +40,7 @@
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_SYS_SELECT_H
 | 
			
		||||
#include <sys/select.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -111,13 +112,18 @@ int pa_poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
 | 
			
		|||
 | 
			
		||||
    if ((ready == -1) && (errno == EBADF)) {
 | 
			
		||||
        ready = 0;
 | 
			
		||||
        maxfd = -1;
 | 
			
		||||
 | 
			
		||||
#ifdef OS_IS_WIN32
 | 
			
		||||
        /*
 | 
			
		||||
         * Windows has no fcntl(), so we have to trick around with more
 | 
			
		||||
         * select() calls to find out what went wrong
 | 
			
		||||
         */
 | 
			
		||||
 | 
			
		||||
        FD_ZERO (&rset);
 | 
			
		||||
        FD_ZERO (&wset);
 | 
			
		||||
        FD_ZERO (&xset);
 | 
			
		||||
 | 
			
		||||
        maxfd = -1;
 | 
			
		||||
 | 
			
		||||
        for (f = fds; f < &fds[nfds]; ++f) {
 | 
			
		||||
            if (f->fd != -1) {
 | 
			
		||||
                fd_set sngl_rset, sngl_wset, sngl_xset;
 | 
			
		||||
| 
						 | 
				
			
			@ -156,6 +162,25 @@ int pa_poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#else /* !OS_IS_WIN32 */
 | 
			
		||||
 | 
			
		||||
        for (f = fds; f < &fds[nfds]; f++)
 | 
			
		||||
            if (f->fd != -1) {
 | 
			
		||||
                /* use fcntl() to find out whether the descriptor is valid */
 | 
			
		||||
                if (fcntl(f->fd, F_GETFL) != -1) {
 | 
			
		||||
                    if (f->fd > maxfd && (f->events & (POLLIN|POLLOUT|POLLPRI))) {
 | 
			
		||||
                        maxfd = f->fd;
 | 
			
		||||
                        ready++;
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    FD_CLR(f->fd, &rset);
 | 
			
		||||
                    FD_CLR(f->fd, &wset);
 | 
			
		||||
                    FD_CLR(f->fd, &xset);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        if (ready) {
 | 
			
		||||
        /* Linux alters the tv struct... but it shouldn't matter here ...
 | 
			
		||||
         * as we're going to be a little bit out anyway as we've just eaten
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue