diff options
author | Lennart Poettering <lennart@poettering.net> | 2010-01-05 22:52:57 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2010-01-05 22:52:57 +0100 |
commit | 6dfb1ee27e031528891696c83230d4513c55b554 (patch) | |
tree | d17bcdf21366097589a024b6f46b33164f832448 /src/pulsecore | |
parent | 937c587e7720ee27b36fe736a2aa1cfd233270ec (diff) | |
parent | f452c6cdd9e5717340807478d759ef5a03b55f1f (diff) |
Merge remote branch 'zonque/topic/osx'
Diffstat (limited to 'src/pulsecore')
-rw-r--r-- | src/pulsecore/core-rtclock.c | 69 | ||||
-rw-r--r-- | src/pulsecore/lock-autospawn.c | 3 | ||||
-rw-r--r-- | src/pulsecore/poll.c | 33 | ||||
-rw-r--r-- | src/pulsecore/poll.h | 18 | ||||
-rw-r--r-- | src/pulsecore/rtpoll.c | 9 |
5 files changed, 75 insertions, 57 deletions
diff --git a/src/pulsecore/core-rtclock.c b/src/pulsecore/core-rtclock.c index 4fe0a47b..110158ba 100644 --- a/src/pulsecore/core-rtclock.c +++ b/src/pulsecore/core-rtclock.c @@ -37,6 +37,7 @@ #include <CoreServices/CoreServices.h> #include <mach/mach.h> #include <mach/mach_time.h> +#include <unistd.h> #endif #include <pulse/timeval.h> @@ -54,7 +55,19 @@ pa_usec_t pa_rtclock_age(const struct timeval *tv) { struct timeval *pa_rtclock_get(struct timeval *tv) { -#if defined(HAVE_CLOCK_GETTIME) +#if defined(OS_IS_DARWIN) + uint64_t val, abs_time = mach_absolute_time(); + Nanoseconds nanos; + + nanos = AbsoluteToNanoseconds(*(AbsoluteTime *) &abs_time); + val = *(uint64_t *) &nanos; + + tv->tv_sec = val / PA_NSEC_PER_SEC; + tv->tv_usec = (val % PA_NSEC_PER_SEC) / PA_NSEC_PER_USEC; + + return tv; + +#elif defined(HAVE_CLOCK_GETTIME) struct timespec ts; #ifdef CLOCK_MONOTONIC @@ -75,65 +88,39 @@ struct timeval *pa_rtclock_get(struct timeval *tv) { tv->tv_usec = ts.tv_nsec / PA_NSEC_PER_USEC; return tv; - -#elif defined(OS_IS_DARWIN) - static mach_timebase_info_data_t tbi; - uint64_t nticks; - uint64_t time_nsec; - - /* Refer Apple ADC QA1398 - Also: http://devworld.apple.com/documentation/Darwin/Conceptual/KernelProgramming/services/services.html - - Note: argument is timespec NOT timeval (timespec uses nsec, timeval uses usec) - */ - - /* try and be a mite efficient - maybe I should keep the N/D as a float !? */ - if (tbi.denom == 0) - mach_timebase_info(&tbi); - - nticks = mach_absolute_time(); - time_nsec = nticks * tbi.numer / tbi.denom; // see above - - tv->tv_sec = time_nsec / PA_NSEC_PER_SEC; - tv->tv_usec = time_nsec / PA_NSEC_PER_USEC; - - return tv; - -#else /* OS_IS_DARWIN */ +#endif /* HAVE_CLOCK_GETTIME */ return pa_gettimeofday(tv); - -#endif } pa_bool_t pa_rtclock_hrtimer(void) { -#if defined(HAVE_CLOCK_GETTIME) +#if defined (OS_IS_DARWIN) + mach_timebase_info_data_t tbi; + uint64_t time_nsec; + + mach_timebase_info(&tbi); + + /* nsec = nticks * (N/D) - we want 1 tick == resolution !? */ + time_nsec = tbi.numer / tbi.denom; + return time_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC); + +#elif defined(HAVE_CLOCK_GETTIME) struct timespec ts; #ifdef CLOCK_MONOTONIC if (clock_getres(CLOCK_MONOTONIC, &ts) >= 0) return ts.tv_sec == 0 && ts.tv_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC); + #endif /* CLOCK_MONOTONIC */ pa_assert_se(clock_getres(CLOCK_REALTIME, &ts) == 0); return ts.tv_sec == 0 && ts.tv_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC); -#elif defined (OS_IS_DARWIN) - mach_timebase_info_data_t tbi; - uint64_t time_nsec; - - mach_timebase_info(&tbi); +#endif /* HAVE_CLOCK_GETTIME */ - /* nsec = nticks * (N/D) - we want 1 tick == resolution !? */ - time_nsec = tbi.numer / tbi.denom; - return time_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC); - -#else /* OS_IS_DARWIN */ return FALSE; - -#endif } #define TIMER_SLACK_NS (int) ((500 * PA_NSEC_PER_USEC)) diff --git a/src/pulsecore/lock-autospawn.c b/src/pulsecore/lock-autospawn.c index 65e35634..95ca04a8 100644 --- a/src/pulsecore/lock-autospawn.c +++ b/src/pulsecore/lock-autospawn.c @@ -33,6 +33,7 @@ #include <pulse/i18n.h> #include <pulse/xmalloc.h> +#include <pulsecore/poll.h> #include <pulsecore/mutex.h> #include <pulsecore/thread.h> #include <pulsecore/core-util.h> @@ -182,7 +183,7 @@ static void wait_for_ping(void) { pfd.fd = pipe_fd[0]; pfd.events = POLLIN; - if ((k = poll(&pfd, 1, -1)) != 1) { + if ((k = pa_poll(&pfd, 1, -1)) != 1) { pa_assert(k < 0); pa_assert(errno == EINTR); } else if ((s = read(pipe_fd[0], &x, 1)) != 1) { diff --git a/src/pulsecore/poll.c b/src/pulsecore/poll.c index 46a69c5f..b98fb169 100644 --- a/src/pulsecore/poll.c +++ b/src/pulsecore/poll.c @@ -35,6 +35,10 @@ #include <config.h> #endif +#ifdef HAVE_SYS_IOCTL_H +#include <sys/ioctl.h> +#endif + #include <errno.h> #ifdef HAVE_SYS_SELECT_H @@ -43,19 +47,26 @@ #include "winsock.h" -#ifndef HAVE_POLL_H - #include <pulsecore/core-util.h> +#include <pulse/util.h> #include "poll.h" -int poll (struct pollfd *fds, unsigned long int nfds, int timeout) { +/* Mac OSX fails to implement poll() in a working way since 10.4. IOW, for + * several years. We need to enable a dirty workaround and emulate that call + * with select(), just like for Windows. sic! */ + +#if !defined(HAVE_POLL_H) || defined(OS_IS_DARWIN) + +int pa_poll (struct pollfd *fds, unsigned long int nfds, int timeout) { struct timeval tv; fd_set rset, wset, xset; struct pollfd *f; int ready; int maxfd = 0; +#ifdef OS_IS_WIN32 char data[64]; +#endif FD_ZERO (&rset); FD_ZERO (&wset); @@ -98,6 +109,7 @@ int poll (struct pollfd *fds, unsigned long int nfds, int timeout) { ready = select ((SELECT_TYPE_ARG1) maxfd + 1, SELECT_TYPE_ARG234 &rset, SELECT_TYPE_ARG234 &wset, SELECT_TYPE_ARG234 &xset, SELECT_TYPE_ARG5 (timeout == -1 ? NULL : &tv)); + if ((ready == -1) && (errno == EBADF)) { ready = 0; @@ -160,6 +172,8 @@ int poll (struct pollfd *fds, unsigned long int nfds, int timeout) { #endif if (ready > 0) { + int r; + ready = 0; for (f = fds; f < &fds[nfds]; ++f) { f->revents = 0; @@ -167,6 +181,18 @@ int poll (struct pollfd *fds, unsigned long int nfds, int timeout) { if (FD_ISSET (f->fd, &rset)) { /* support for POLLHUP. An hung up descriptor does not increase the return value! */ +#ifdef OS_IS_DARWIN + /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK + * for some kinds of descriptors. Detect if this descriptor is a + * connected socket, a server socket, or something else using a + * 0-byte recv, and use ioctl(2) to detect POLLHUP. */ + r = recv(f->fd, NULL, 0, MSG_PEEK); + if (r == 0 || (r < 0 && errno == ENOTSOCK)) + ioctl(f->fd, FIONREAD, &r); + + if (r == 0) + f->revents |= POLLHUP; +#else /* !OS_IS_DARWIN */ if (recv (f->fd, data, 64, MSG_PEEK) == -1) { if (errno == ESHUTDOWN || errno == ECONNRESET || errno == ECONNABORTED || errno == ENETRESET) { @@ -174,6 +200,7 @@ int poll (struct pollfd *fds, unsigned long int nfds, int timeout) { f->revents |= POLLHUP; } } +#endif if (f->revents == 0) f->revents |= POLLIN; diff --git a/src/pulsecore/poll.h b/src/pulsecore/poll.h index fe0c6af6..a137d974 100644 --- a/src/pulsecore/poll.h +++ b/src/pulsecore/poll.h @@ -24,6 +24,10 @@ Copyright (C) 1994,96,97,98,99,2000,2001,2004 Free Software Foundation, Inc. ***/ +#if defined(HAVE_POLL_H) +#include <poll.h> +#else + /* Event types that can be polled for. These bits may be set in `events' to indicate the interesting event types; they will appear in `revents' to indicate the status of the file descriptor. */ @@ -38,10 +42,6 @@ #define POLLHUP 0x010 /* Hung up. */ #define POLLNVAL 0x020 /* Invalid polling request. */ - -/* Type used for the number of file descriptors. */ -typedef unsigned long int nfds_t; - /* Data structure describing a polling request. */ struct pollfd { @@ -50,9 +50,17 @@ struct pollfd short int revents; /* Types of events that actually occurred. */ }; + /* Poll the file descriptors described by the NFDS structures starting at FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for an event to occur; if TIMEOUT is -1, block until an event occurs. Returns the number of file descriptors with events, zero if timed out, or -1 for errors. */ -extern int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout); + +#endif /* HAVE_POLL_H */ + +#if defined(HAVE_POLL_H) && !defined(OS_IS_DARWIN) +#define pa_poll(fds,nfds,timeout) poll((fds),(nfds),(timeout)) +#else +int pa_poll (struct pollfd *fds, unsigned long nfds, int timeout); +#endif diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index e2f82626..2ef78736 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -30,15 +30,10 @@ #include <string.h> #include <errno.h> -#ifdef HAVE_POLL_H -#include <poll.h> -#else -#include <pulsecore/poll.h> -#endif - #include <pulse/xmalloc.h> #include <pulse/timeval.h> +#include <pulsecore/poll.h> #include <pulsecore/core-error.h> #include <pulsecore/core-rtclock.h> #include <pulsecore/macro.h> @@ -321,7 +316,7 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait_op) { r = ppoll(p->pollfd, p->n_pollfd_used, (!wait_op || p->quit || p->timer_enabled) ? &ts : NULL, NULL); } #else - r = poll(p->pollfd, p->n_pollfd_used, (!wait_op || p->quit || p->timer_enabled) ? (int) ((timeout.tv_sec*1000) + (timeout.tv_usec / 1000)) : -1); + r = pa_poll(p->pollfd, p->n_pollfd_used, (!wait_op || p->quit || p->timer_enabled) ? (int) ((timeout.tv_sec*1000) + (timeout.tv_usec / 1000)) : -1); #endif p->timer_elapsed = r == 0; |