From a46ddfebb592852ff791bc90b3953880c49073dd Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Sun, 1 Nov 2009 20:06:08 +0100 Subject: core-rtclock.c: tweak OS_IS_DARWIN constraints Move the code for OS_IS_DARWIN to the top as on Darwin, HAVE_CLOCK_GETTIME is also defined. --- src/pulsecore/core-rtclock.c | 69 ++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 41 deletions(-) (limited to 'src/pulsecore') 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 #include #include +#include #endif #include @@ -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)) -- cgit From 17d34462eace417075efa2314999a77e41a3849b Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Mon, 23 Nov 2009 00:12:18 +0100 Subject: poll() is totally broken on Mac OS X Even on 10.5.8, poll() does not do the right thing. Haven't checked on newer versions. Hence, wrap all occurences of poll() to pa_poll and emulate that call with select() on OSX. This is totally embarassing. --- src/pulsecore/lock-autospawn.c | 3 ++- src/pulsecore/poll.c | 11 ++++++++--- src/pulsecore/poll.h | 18 +++++++++++++----- src/pulsecore/rtpoll.c | 9 ++------- 4 files changed, 25 insertions(+), 16 deletions(-) (limited to 'src/pulsecore') 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 #include +#include #include #include #include @@ -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..1dcace8b 100644 --- a/src/pulsecore/poll.c +++ b/src/pulsecore/poll.c @@ -43,13 +43,18 @@ #include "winsock.h" -#ifndef HAVE_POLL_H - #include +#include #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; 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 +#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 666cbc98..83993f02 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -30,15 +30,10 @@ #include #include -#ifdef HAVE_POLL_H -#include -#else -#include -#endif - #include #include +#include #include #include #include @@ -304,7 +299,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; -- cgit From 28a73ad1203efc6f6dc33629ce653f45081210fa Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Mon, 7 Dec 2009 00:40:03 +0100 Subject: hack around another OS X bug: recv() with MSG_PEEK does not work At least for pipes, recv() with MSG_PEEK does actually eat up data from file descriptors. Hence, this can't be used for PULLHUP emulation. Use another ioctl hack for that. --- src/pulsecore/poll.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/pulsecore') diff --git a/src/pulsecore/poll.c b/src/pulsecore/poll.c index 1dcace8b..b98fb169 100644 --- a/src/pulsecore/poll.c +++ b/src/pulsecore/poll.c @@ -35,6 +35,10 @@ #include #endif +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + #include #ifdef HAVE_SYS_SELECT_H @@ -60,7 +64,9 @@ int pa_poll (struct pollfd *fds, unsigned long int nfds, int timeout) { struct pollfd *f; int ready; int maxfd = 0; +#ifdef OS_IS_WIN32 char data[64]; +#endif FD_ZERO (&rset); FD_ZERO (&wset); @@ -103,6 +109,7 @@ int pa_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; @@ -165,6 +172,8 @@ int pa_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; @@ -172,6 +181,18 @@ int pa_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) { @@ -179,6 +200,7 @@ int pa_poll (struct pollfd *fds, unsigned long int nfds, int timeout) { f->revents |= POLLHUP; } } +#endif if (f->revents == 0) f->revents |= POLLIN; -- cgit From f452c6cdd9e5717340807478d759ef5a03b55f1f Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 10 Dec 2009 15:42:40 +0800 Subject: fix a number of warnings most of them were due to missing #ifdefs or wrong printf format type for [s]size_t. --- src/pulsecore/core-util.c | 4 ++-- src/pulsecore/envelope.c | 8 +++----- src/pulsecore/sink-input.c | 12 +++++++----- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/pulsecore') diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index d596c481..b64c51e1 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -580,8 +580,8 @@ char *pa_strlcpy(char *b, const char *s, size_t l) { static int set_scheduler(int rtprio) { struct sched_param sp; - int r; #ifdef HAVE_DBUS + int r; DBusError error; DBusConnection *bus; @@ -628,7 +628,7 @@ static int set_scheduler(int rtprio) { errno = -r; #else - errno = r; + errno = 0; #endif return -1; diff --git a/src/pulsecore/envelope.c b/src/pulsecore/envelope.c index 0eca8115..75e189cb 100644 --- a/src/pulsecore/envelope.c +++ b/src/pulsecore/envelope.c @@ -597,7 +597,7 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) { fs = pa_frame_size(&e->sample_spec); n = chunk->length; - pa_log_debug("Envelop position %d applying factor %d=%f, sample spec is %d, chunk's length is %d, fs is %d\n", e->x, linear_get_int(e, v), ((float) linear_get_int(e,v))/0x10000, e->sample_spec.format, n, fs); + pa_log_debug("Envelop position %zu applying factor %d=%f, sample spec is %d, chunk's length is %zu, fs is %zu\n", e->x, linear_get_int(e, v), ((float) linear_get_int(e,v))/0x10000, e->sample_spec.format, n, fs); switch (e->sample_spec.format) { @@ -965,11 +965,10 @@ void pa_envelope_restart(pa_envelope* e) { } pa_bool_t pa_envelope_is_finished(pa_envelope* e) { - pa_assert(e); - int v; pa_bool_t finished; + pa_assert(e); envelope_begin_read(e, &v); finished = (e->x >= e->points[v].x[e->points[v].n_points-1]); envelope_commit_read(e, v); @@ -978,11 +977,10 @@ pa_bool_t pa_envelope_is_finished(pa_envelope* e) { } int32_t pa_envelope_length(pa_envelope *e) { - pa_assert(e); - int v; size_t size; + pa_assert(e); envelope_begin_read(e, &v); size = e->points[v].x[e->points[v].n_points-1] - e->points[v].x[0]; envelope_commit_read(e, v); diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c index 35e3d4a9..9b4edeb9 100644 --- a/src/pulsecore/sink-input.c +++ b/src/pulsecore/sink-input.c @@ -779,11 +779,11 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p if (!i->thread_info.ramp_info.envelope_dead) { i->thread_info.ramp_info.envelope_dying += chunk->length; - pa_log_debug("Envelope dying is %d, chunk length is %d, dead thresholder is %d\n", i->thread_info.ramp_info.envelope_dying, + pa_log_debug("Envelope dying is %d, chunk length is %zu, dead thresholder is %lu\n", i->thread_info.ramp_info.envelope_dying, chunk->length, i->sink->thread_info.max_rewind + pa_envelope_length(i->thread_info.ramp_info.envelope)); - if (i->thread_info.ramp_info.envelope_dying >= (i->sink->thread_info.max_rewind + pa_envelope_length(i->thread_info.ramp_info.envelope))) { + if (i->thread_info.ramp_info.envelope_dying >= (int32_t) (i->sink->thread_info.max_rewind + pa_envelope_length(i->thread_info.ramp_info.envelope))) { pa_log_debug("RELEASE Envelop"); i->thread_info.ramp_info.envelope_dead = TRUE; sink_input_release_envelope(i); @@ -1767,12 +1767,14 @@ static void sink_input_rewind_ramp_info(pa_sink_input *i, size_t nbytes) { pa_assert(i); if (!i->thread_info.ramp_info.envelope_dead) { - pa_assert(i->thread_info.ramp_info.envelope); + int32_t envelope_length; - int32_t envelope_length = pa_envelope_length(i->thread_info.ramp_info.envelope); + pa_assert(i->thread_info.ramp_info.envelope); + + envelope_length = pa_envelope_length(i->thread_info.ramp_info.envelope); if (i->thread_info.ramp_info.envelope_dying > envelope_length) { - if ((i->thread_info.ramp_info.envelope_dying - nbytes) < envelope_length) { + if ((int32_t) (i->thread_info.ramp_info.envelope_dying - nbytes) < envelope_length) { pa_log_debug("Envelope Become Alive"); pa_envelope_rewind(i->thread_info.ramp_info.envelope, envelope_length - (i->thread_info.ramp_info.envelope_dying - nbytes)); i->thread_info.ramp_info.is_ramping = TRUE; -- cgit