X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gst%2Fgstpoll.c;h=5e0a668a89d92456b1be6f846940963b67bb6e51;hb=f34472822c257359d69ebf671b81d85646a40618;hp=7aab1d1a71e1211206b53f427daa6b3144c2f26b;hpb=1d052f0ccef9872a2d7c82e4286298f34df13b95;p=platform%2Fupstream%2Fgstreamer.git diff --git a/gst/gstpoll.c b/gst/gstpoll.c index 7aab1d1..5e0a668 100644 --- a/gst/gstpoll.c +++ b/gst/gstpoll.c @@ -2,7 +2,7 @@ * Copyright (C) 1999 Erik Walthinsen * Copyright (C) 2004 Wim Taymans * Copyright (C) 2007 Peter Kjellerstedt - * Copyright (C) 2008 Ole André Vadla Ravnås + * Copyright (C) 2008 Ole André Vadla RavnÃ¥s * * gstpoll.c: File descriptor set * @@ -18,13 +18,14 @@ * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. */ /** * SECTION:gstpoll + * @title: GstPoll * @short_description: Keep track of file descriptors and make it possible - * to wait on them in a cancelable way + * to wait on them in a cancellable way * * A #GstPoll keeps track of file descriptors much like fd_set (used with * select()) or a struct pollfd array (used with poll()). Once created with @@ -36,7 +37,7 @@ * New file descriptors are added to the set using gst_poll_add_fd(), and * removed using gst_poll_remove_fd(). Controlling which file descriptors * should be waited for to become readable and/or writable are done using - * gst_poll_fd_ctl_read() and gst_poll_fd_ctl_write(). + * gst_poll_fd_ctl_read(), gst_poll_fd_ctl_write() and gst_poll_fd_ctl_pri(). * * Use gst_poll_wait() to wait for the file descriptors to actually become * readable and/or writable, or to timeout if no file descriptor is available @@ -72,7 +73,6 @@ #ifdef G_OS_WIN32 #include -#define EINPROGRESS WSAEINPROGRESS #else #define _GNU_SOURCE 1 #ifdef HAVE_SYS_POLL_H @@ -85,6 +85,12 @@ #include #endif +#ifdef G_OS_WIN32 +# ifndef EWOULDBLOCK +# define EWOULDBLOCK EAGAIN /* This is just to placate gcc */ +# endif +#endif /* G_OS_WIN32 */ + /* OS/X needs this because of bad headers */ #include @@ -134,7 +140,6 @@ struct _GstPoll GArray *active_fds; #ifndef G_OS_WIN32 - gchar buf[1]; GstPollFD control_read_fd; GstPollFD control_write_fd; #else @@ -168,11 +173,106 @@ static gboolean gst_poll_add_fd_unlocked (GstPoll * set, GstPollFD * fd); #define MARK_REBUILD(s) (g_atomic_int_set(&(s)->rebuild, 1)) #ifndef G_OS_WIN32 -#define WAKE_EVENT(s) (write ((s)->control_write_fd.fd, "W", 1) == 1) -#define RELEASE_EVENT(s) (read ((s)->control_read_fd.fd, (s)->buf, 1) == 1) + +static gboolean +wake_event (GstPoll * set) +{ + ssize_t num_written; + while ((num_written = write (set->control_write_fd.fd, "W", 1)) != 1) { + if (num_written == -1 && errno != EAGAIN && errno != EINTR) { + g_critical ("%p: failed to wake event: %s", set, strerror (errno)); + return FALSE; + } + } + return TRUE; +} + +static gboolean +release_event (GstPoll * set) +{ + gchar buf[1] = { '\0' }; + ssize_t num_read; + while ((num_read = read (set->control_read_fd.fd, buf, 1)) != 1) { + if (num_read == -1 && errno != EAGAIN && errno != EINTR) { + g_critical ("%p: failed to release event: %s", set, strerror (errno)); + return FALSE; + } + } + return TRUE; +} + #else -#define WAKE_EVENT(s) (SetEvent ((s)->wakeup_event), errno = GetLastError () == NO_ERROR ? 0 : EACCES, errno == 0 ? 1 : 0) -#define RELEASE_EVENT(s) (ResetEvent ((s)->wakeup_event)) + +static void +format_last_error (gchar * buf, size_t buf_len) +{ + DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM; + LPCVOID src = NULL; + DWORD lang = 0; + DWORD id; + id = GetLastError (); + FormatMessage (flags, src, id, lang, buf, (DWORD) buf_len, NULL); + SetLastError (id); +} + +static gboolean +wake_event (GstPoll * set) +{ + SetLastError (0); + errno = 0; + if (!SetEvent (set->wakeup_event)) { + gchar msg[1024] = ""; + format_last_error (msg, sizeof (msg)); + g_critical ("%p: failed to set wakup_event: %s", set, msg); + errno = EBADF; + return FALSE; + } + + return TRUE; +} + +static gboolean +release_event (GstPoll * set) +{ + DWORD status; + SetLastError (0); + errno = 0; + + status = WaitForSingleObject (set->wakeup_event, INFINITE); + if (status) { + const gchar *reason = "unknown"; + gchar msg[1024] = ""; + switch (status) { + case WAIT_ABANDONED: + reason = "WAIT_ABANDONED"; + break; + case WAIT_TIMEOUT: + reason = "WAIT_TIMEOUT"; + break; + case WAIT_FAILED: + format_last_error (msg, sizeof (msg)); + reason = msg; + break; + default: + reason = "other"; + break; + } + g_critical ("%p: failed to block on wakup_event: %s", set, reason); + errno = EBADF; + return FALSE; + } + + if (!ResetEvent (set->wakeup_event)) { + gchar msg[1024] = ""; + format_last_error (msg, sizeof (msg)); + g_critical ("%p: failed to reset wakup_event: %s", set, msg); + errno = EBADF; + return FALSE; + } + + return TRUE; +} + #endif /* the poll/select call is also performed on a control socket, that way @@ -182,26 +282,50 @@ raise_wakeup (GstPoll * set) { gboolean result = TRUE; - if (g_atomic_int_add (&set->control_pending, 1) == 0) { + /* makes testing control_pending and WAKE_EVENT() atomic. */ + g_mutex_lock (&set->lock); + + if (set->control_pending == 0) { /* raise when nothing pending */ GST_LOG ("%p: raise", set); - result = WAKE_EVENT (set); + result = wake_event (set); + } + + if (result) { + set->control_pending++; } + + g_mutex_unlock (&set->lock); + return result; } -/* note how bad things can happen when the 2 threads both raise and release the - * wakeup. This is however not a problem because you must always pair a raise - * with a release */ static inline gboolean release_wakeup (GstPoll * set) { - gboolean result = TRUE; + gboolean result = FALSE; + + /* makes testing/modifying control_pending and RELEASE_EVENT() atomic. */ + g_mutex_lock (&set->lock); - if (g_atomic_int_dec_and_test (&set->control_pending)) { - GST_LOG ("%p: release", set); - result = RELEASE_EVENT (set); + if (set->control_pending > 0) { + /* release, only if this was the last pending. */ + if (set->control_pending == 1) { + GST_LOG ("%p: release", set); + result = release_event (set); + } else { + result = TRUE; + } + + if (result) { + set->control_pending--; + } + } else { + errno = EWOULDBLOCK; } + + g_mutex_unlock (&set->lock); + return result; } @@ -210,21 +334,20 @@ release_all_wakeup (GstPoll * set) { gint old; - while (TRUE) { - if (!(old = g_atomic_int_get (&set->control_pending))) - /* nothing pending, just exit */ - break; + /* makes testing control_pending and RELEASE_EVENT() atomic. */ + g_mutex_lock (&set->lock); - /* try to remove all pending control messages */ - if (g_atomic_int_compare_and_exchange (&set->control_pending, old, 0)) { - /* we managed to remove all messages, read the control socket */ - if (RELEASE_EVENT (set)) - break; - else - /* retry again until we read it successfully */ - g_atomic_int_add (&set->control_pending, 1); + if ((old = set->control_pending) > 0) { + GST_LOG ("%p: releasing %d", set, old); + if (release_event (set)) { + set->control_pending = 0; + } else { + old = 0; } } + + g_mutex_unlock (&set->lock); + return old; } @@ -272,7 +395,7 @@ find_index (GArray * array, GstPollFD * fd) #if !defined(HAVE_PPOLL) && defined(HAVE_POLL) /* check if all file descriptors will fit in an fd_set */ static gboolean -selectable_fds (const GstPoll * set) +selectable_fds (GstPoll * set) { guint i; @@ -312,7 +435,7 @@ pollable_timeout (GstClockTime timeout) #endif static GstPollMode -choose_mode (const GstPoll * set, GstClockTime timeout) +choose_mode (GstPoll * set, GstClockTime timeout) { GstPollMode mode; @@ -546,19 +669,16 @@ gst_poll_collect_winsock_events (GstPoll * set) * * Free-function: gst_poll_free * - * Returns: (transfer full): a new #GstPoll, or %NULL in case of an error. - * Free with gst_poll_free(). - * - * Since: 0.10.18 + * Returns: (transfer full) (nullable): a new #GstPoll, or %NULL in + * case of an error. Free with gst_poll_free(). */ GstPoll * gst_poll_new (gboolean controllable) { GstPoll *nset; - GST_DEBUG ("controllable : %d", controllable); - nset = g_slice_new0 (GstPoll); + GST_DEBUG ("%p: new controllable : %d", nset, controllable); g_mutex_init (&nset->lock); #ifndef G_OS_WIN32 nset->mode = GST_POLL_MODE_AUTO; @@ -572,9 +692,6 @@ gst_poll_new (gboolean controllable) if (socketpair (PF_UNIX, SOCK_STREAM, 0, control_sock) < 0) goto no_socket_pair; - fcntl (control_sock[0], F_SETFL, O_NONBLOCK); - fcntl (control_sock[1], F_SETFL, O_NONBLOCK); - nset->control_read_fd.fd = control_sock[0]; nset->control_write_fd.fd = control_sock[1]; @@ -596,6 +713,7 @@ gst_poll_new (gboolean controllable) MARK_REBUILD (nset); nset->controllable = controllable; + nset->control_pending = 0; return nset; @@ -617,14 +735,12 @@ no_socket_pair: * timeouts. * * A timeout is performed with gst_poll_wait(). Multiple timeouts can be - * performed from different threads. + * performed from different threads. * * Free-function: gst_poll_free * - * Returns: (transfer full): a new #GstPoll, or %NULL in case of an error. - * Free with gst_poll_free(). - * - * Since: 0.10.23 + * Returns: (transfer full) (nullable): a new #GstPoll, or %NULL in + * case of an error. Free with gst_poll_free(). */ GstPoll * gst_poll_new_timer (void) @@ -647,8 +763,6 @@ done: * @set: (transfer full): a file descriptor set. * * Free a file descriptor set. - * - * Since: 0.10.18 */ void gst_poll_free (GstPoll * set) @@ -690,8 +804,6 @@ gst_poll_free (GstPoll * set) * * Get a GPollFD for the reading part of the control socket. This is useful when * integrating with a GSource and GMainLoop. - * - * Since: 0.10.32 */ void gst_poll_get_read_gpollfd (GstPoll * set, GPollFD * fd) @@ -718,8 +830,6 @@ gst_poll_get_read_gpollfd (GstPoll * set, GPollFD * fd) * * Initializes @fd. Alternatively you can initialize it with * #GST_POLL_FD_INIT. - * - * Since: 0.10.18 */ void gst_poll_fd_init (GstPollFD * fd) @@ -766,7 +876,7 @@ gst_poll_add_fd_unlocked (GstPoll * set, GstPollFD * fd) #endif MARK_REBUILD (set); } else { - GST_WARNING ("%p: couldn't find fd !", set); + GST_WARNING ("%p: fd already added !", set); } return TRUE; @@ -780,8 +890,6 @@ gst_poll_add_fd_unlocked (GstPoll * set, GstPollFD * fd) * Add a file descriptor to the file descriptor set. * * Returns: %TRUE if the file descriptor was successfully added to the set. - * - * Since: 0.10.18 */ gboolean gst_poll_add_fd (GstPoll * set, GstPollFD * fd) @@ -809,8 +917,6 @@ gst_poll_add_fd (GstPoll * set, GstPollFD * fd) * Remove a file descriptor from the file descriptor set. * * Returns: %TRUE if the file descriptor was successfully removed from the set. - * - * Since: 0.10.18 */ gboolean gst_poll_remove_fd (GstPoll * set, GstPollFD * fd) @@ -860,8 +966,6 @@ gst_poll_remove_fd (GstPoll * set, GstPollFD * fd) * writability. * * Returns: %TRUE if the descriptor was successfully updated. - * - * Since: 0.10.18 */ gboolean gst_poll_fd_ctl_write (GstPoll * set, GstPollFD * fd, gboolean active) @@ -887,7 +991,7 @@ gst_poll_fd_ctl_write (GstPoll * set, GstPollFD * fd, gboolean active) else pfd->events &= ~POLLOUT; - GST_LOG ("pfd->events now %d (POLLOUT:%d)", pfd->events, POLLOUT); + GST_LOG ("%p: pfd->events now %d (POLLOUT:%d)", set, pfd->events, POLLOUT); #else gst_poll_update_winsock_event_mask (set, idx, FD_WRITE | FD_CONNECT, active); @@ -917,9 +1021,9 @@ gst_poll_fd_ctl_read_unlocked (GstPoll * set, GstPollFD * fd, gboolean active) struct pollfd *pfd = &g_array_index (set->fds, struct pollfd, idx); if (active) - pfd->events |= (POLLIN | POLLPRI); + pfd->events |= POLLIN; else - pfd->events &= ~(POLLIN | POLLPRI); + pfd->events &= ~POLLIN; #else gst_poll_update_winsock_event_mask (set, idx, FD_READ | FD_ACCEPT, active); #endif @@ -941,8 +1045,6 @@ gst_poll_fd_ctl_read_unlocked (GstPoll * set, GstPollFD * fd, gboolean active) * readability. * * Returns: %TRUE if the descriptor was successfully updated. - * - * Since: 0.10.18 */ gboolean gst_poll_fd_ctl_read (GstPoll * set, GstPollFD * fd, gboolean active) @@ -963,6 +1065,59 @@ gst_poll_fd_ctl_read (GstPoll * set, GstPollFD * fd, gboolean active) } /** + * gst_poll_fd_ctl_pri: + * @set: a file descriptor set. + * @fd: a file descriptor. + * @active: a new status. + * + * Control whether the descriptor @fd in @set will be monitored for + * exceptional conditions (POLLPRI). + * + * Not implemented on Windows (will just return %FALSE there). + * + * Returns: %TRUE if the descriptor was successfully updated. + * + * Since: 1.16 + */ +gboolean +gst_poll_fd_ctl_pri (GstPoll * set, GstPollFD * fd, gboolean active) +{ +#ifdef G_OS_WIN32 + return FALSE; +#else + gint idx; + + g_return_val_if_fail (set != NULL, FALSE); + g_return_val_if_fail (fd != NULL, FALSE); + g_return_val_if_fail (fd->fd >= 0, FALSE); + + GST_DEBUG ("%p: fd (fd:%d, idx:%d), active : %d", set, + fd->fd, fd->idx, active); + + g_mutex_lock (&set->lock); + + idx = find_index (set->fds, fd); + if (idx >= 0) { + struct pollfd *pfd = &g_array_index (set->fds, struct pollfd, idx); + + if (active) + pfd->events |= POLLPRI; + else + pfd->events &= ~POLLPRI; + + GST_LOG ("%p: pfd->events now %d (POLLPRI:%d)", set, pfd->events, POLLOUT); + MARK_REBUILD (set); + } else { + GST_WARNING ("%p: couldn't find fd !", set); + } + + g_mutex_unlock (&set->lock); + + return idx >= 0; +#endif +} + +/** * gst_poll_fd_ignored: * @set: a file descriptor set. * @fd: a file descriptor. @@ -975,8 +1130,6 @@ gst_poll_fd_ctl_read (GstPoll * set, GstPollFD * fd, gboolean active) * The reason why this is needed is because the underlying implementation * might not allow querying the fd more than once between calls to one of * the re-enabling operations. - * - * Since: 0.10.18 */ void gst_poll_fd_ignored (GstPoll * set, GstPollFD * fd) @@ -1010,8 +1163,6 @@ gst_poll_fd_ignored (GstPoll * set, GstPollFD * fd) * Check if @fd in @set has closed the connection. * * Returns: %TRUE if the connection was closed. - * - * Since: 0.10.18 */ gboolean gst_poll_fd_has_closed (const GstPoll * set, GstPollFD * fd) @@ -1023,8 +1174,6 @@ gst_poll_fd_has_closed (const GstPoll * set, GstPollFD * fd) g_return_val_if_fail (fd != NULL, FALSE); g_return_val_if_fail (fd->fd >= 0, FALSE); - GST_DEBUG ("%p: fd (fd:%d, idx:%d)", set, fd->fd, fd->idx); - g_mutex_lock (&((GstPoll *) set)->lock); idx = find_index (set->active_fds, fd); @@ -1041,9 +1190,10 @@ gst_poll_fd_has_closed (const GstPoll * set, GstPollFD * fd) } else { GST_WARNING ("%p: couldn't find fd !", set); } - g_mutex_unlock (&((GstPoll *) set)->lock); + GST_DEBUG ("%p: fd (fd:%d, idx:%d) %d", set, fd->fd, fd->idx, res); + return res; } @@ -1055,8 +1205,6 @@ gst_poll_fd_has_closed (const GstPoll * set, GstPollFD * fd) * Check if @fd in @set has an error. * * Returns: %TRUE if the descriptor has an error. - * - * Since: 0.10.18 */ gboolean gst_poll_fd_has_error (const GstPoll * set, GstPollFD * fd) @@ -1068,8 +1216,6 @@ gst_poll_fd_has_error (const GstPoll * set, GstPollFD * fd) g_return_val_if_fail (fd != NULL, FALSE); g_return_val_if_fail (fd->fd >= 0, FALSE); - GST_DEBUG ("%p: fd (fd:%d, idx:%d)", set, fd->fd, fd->idx); - g_mutex_lock (&((GstPoll *) set)->lock); idx = find_index (set->active_fds, fd); @@ -1090,9 +1236,10 @@ gst_poll_fd_has_error (const GstPoll * set, GstPollFD * fd) } else { GST_WARNING ("%p: couldn't find fd !", set); } - g_mutex_unlock (&((GstPoll *) set)->lock); + GST_DEBUG ("%p: fd (fd:%d, idx:%d) %d", set, fd->fd, fd->idx, res); + return res; } @@ -1102,14 +1249,12 @@ gst_poll_fd_can_read_unlocked (const GstPoll * set, GstPollFD * fd) gboolean res = FALSE; gint idx; - GST_DEBUG ("%p: fd (fd:%d, idx:%d)", set, fd->fd, fd->idx); - idx = find_index (set->active_fds, fd); if (idx >= 0) { #ifndef G_OS_WIN32 struct pollfd *pfd = &g_array_index (set->active_fds, struct pollfd, idx); - res = (pfd->revents & (POLLIN | POLLPRI)) != 0; + res = (pfd->revents & POLLIN) != 0; #else WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, idx); @@ -1118,6 +1263,7 @@ gst_poll_fd_can_read_unlocked (const GstPoll * set, GstPollFD * fd) } else { GST_WARNING ("%p: couldn't find fd !", set); } + GST_DEBUG ("%p: fd (fd:%d, idx:%d) %d", set, fd->fd, fd->idx, res); return res; } @@ -1130,8 +1276,6 @@ gst_poll_fd_can_read_unlocked (const GstPoll * set, GstPollFD * fd) * Check if @fd in @set has data to be read. * * Returns: %TRUE if the descriptor has data to be read. - * - * Since: 0.10.18 */ gboolean gst_poll_fd_can_read (const GstPoll * set, GstPollFD * fd) @@ -1159,8 +1303,6 @@ gst_poll_fd_can_read (const GstPoll * set, GstPollFD * fd) * Check if @fd in @set can be used for writing. * * Returns: %TRUE if the descriptor can be used for writing. - * - * Since: 0.10.18 */ gboolean gst_poll_fd_can_write (const GstPoll * set, GstPollFD * fd) @@ -1172,8 +1314,6 @@ gst_poll_fd_can_write (const GstPoll * set, GstPollFD * fd) g_return_val_if_fail (fd != NULL, FALSE); g_return_val_if_fail (fd->fd >= 0, FALSE); - GST_DEBUG ("%p: fd (fd:%d, idx:%d)", set, fd->fd, fd->idx); - g_mutex_lock (&((GstPoll *) set)->lock); idx = find_index (set->active_fds, fd); @@ -1190,10 +1330,55 @@ gst_poll_fd_can_write (const GstPoll * set, GstPollFD * fd) } else { GST_WARNING ("%p: couldn't find fd !", set); } + g_mutex_unlock (&((GstPoll *) set)->lock); + + GST_DEBUG ("%p: fd (fd:%d, idx:%d) %d", set, fd->fd, fd->idx, res); + + return res; +} +/** + * gst_poll_fd_has_pri: + * @set: a file descriptor set. + * @fd: a file descriptor. + * + * Check if @fd in @set has an exceptional condition (POLLPRI). + * + * Not implemented on Windows (will just return %FALSE there). + * + * Returns: %TRUE if the descriptor has an exceptional condition. + * + * Since: 1.16 + */ +gboolean +gst_poll_fd_has_pri (const GstPoll * set, GstPollFD * fd) +{ +#ifdef G_OS_WIN32 + return FALSE; +#else + gboolean res = FALSE; + gint idx; + + g_return_val_if_fail (set != NULL, FALSE); + g_return_val_if_fail (fd != NULL, FALSE); + g_return_val_if_fail (fd->fd >= 0, FALSE); + + g_mutex_lock (&((GstPoll *) set)->lock); + + idx = find_index (set->active_fds, fd); + if (idx >= 0) { + struct pollfd *pfd = &g_array_index (set->active_fds, struct pollfd, idx); + + res = (pfd->revents & POLLPRI) != 0; + } else { + GST_WARNING ("%p: couldn't find fd !", set); + } g_mutex_unlock (&((GstPoll *) set)->lock); + GST_DEBUG ("%p: fd (fd:%d, idx:%d) %d", set, fd->fd, fd->idx, res); + return res; +#endif } /** @@ -1215,8 +1400,6 @@ gst_poll_fd_can_write (const GstPoll * set, GstPollFD * fd) * Returns: The number of #GstPollFD in @set that have activity or 0 when no * activity was detected after @timeout. If an error occurs, -1 is returned * and errno is set. - * - * Since: 0.10.18 */ gint gst_poll_wait (GstPoll * set, GstClockTime timeout) @@ -1228,7 +1411,7 @@ gst_poll_wait (GstPoll * set, GstClockTime timeout) g_return_val_if_fail (set != NULL, -1); - GST_DEBUG ("timeout :%" GST_TIME_FORMAT, GST_TIME_ARGS (timeout)); + GST_DEBUG ("%p: timeout :%" GST_TIME_FORMAT, set, GST_TIME_ARGS (timeout)); is_timer = set->timer; @@ -1339,9 +1522,9 @@ gst_poll_wait (GstPoll * set, GstClockTime timeout) tvptr = NULL; } - GST_DEBUG ("Calling select"); + GST_DEBUG ("%p: Calling select", set); res = select (max_fd + 1, &readfds, &writefds, &errorfds, tvptr); - GST_DEBUG ("After select, res:%d", res); + GST_DEBUG ("%p: After select, res:%d", set, res); } else { #ifdef HAVE_PSELECT struct timespec ts; @@ -1354,10 +1537,10 @@ gst_poll_wait (GstPoll * set, GstClockTime timeout) tsptr = NULL; } - GST_DEBUG ("Calling pselect"); + GST_DEBUG ("%p: Calling pselect", set); res = pselect (max_fd + 1, &readfds, &writefds, &errorfds, tsptr, NULL); - GST_DEBUG ("After pselect, res:%d", res); + GST_DEBUG ("%p: After pselect, res:%d", set, res); #endif } @@ -1470,14 +1653,16 @@ winsock_error: * gst_poll_wait() will be affected by gst_poll_restart() and * gst_poll_set_flushing(). * - * Returns: %TRUE if the controllability of @set could be updated. + * This function only works for non-timer #GstPoll objects created with + * gst_poll_new(). * - * Since: 0.10.18 + * Returns: %TRUE if the controllability of @set could be updated. */ gboolean gst_poll_set_controllable (GstPoll * set, gboolean controllable) { g_return_val_if_fail (set != NULL, FALSE); + g_return_val_if_fail (!set->timer, FALSE); GST_LOG ("%p: controllable : %d", set, controllable); @@ -1495,12 +1680,14 @@ gst_poll_set_controllable (GstPoll * set, gboolean controllable) * * If @set is not controllable, then this call will have no effect. * - * Since: 0.10.18 + * This function only works for non-timer #GstPoll objects created with + * gst_poll_new(). */ void gst_poll_restart (GstPoll * set) { g_return_if_fail (set != NULL); + g_return_if_fail (!set->timer); if (set->controllable && GET_WAITING (set) > 0) { /* we are controllable and waiting, wake up the waiter. The socket will be @@ -1519,12 +1706,14 @@ gst_poll_restart (GstPoll * set) * * Unsetting the flushing state will restore normal operation of @set. * - * Since: 0.10.18 + * This function only works for non-timer #GstPoll objects created with + * gst_poll_new(). */ void gst_poll_set_flushing (GstPoll * set, gboolean flushing) { g_return_if_fail (set != NULL); + g_return_if_fail (!set->timer); GST_LOG ("%p: flushing: %d", set, flushing); @@ -1545,17 +1734,19 @@ gst_poll_set_flushing (GstPoll * set, gboolean flushing) * * Write a byte to the control socket of the controllable @set. * This function is mostly useful for timer #GstPoll objects created with - * gst_poll_new_timer(). + * gst_poll_new_timer(). * * It will make any current and future gst_poll_wait() function return with * 1, meaning the control socket is set. After an equal amount of calls to * gst_poll_read_control() have been performed, calls to gst_poll_wait() will * block again until their timeout expired. * - * Returns: %TRUE on success. %FALSE when @set is not controllable or when the - * byte could not be written. + * This function only works for timer #GstPoll objects created with + * gst_poll_new_timer(). * - * Since: 0.10.23 + * Returns: %TRUE on success. %FALSE when when the byte could not be written. + * errno contains the detailed error code but will never be EAGAIN, EINTR or + * EWOULDBLOCK. %FALSE always signals a critical error. */ gboolean gst_poll_write_control (GstPoll * set) @@ -1575,13 +1766,14 @@ gst_poll_write_control (GstPoll * set) * @set: a #GstPoll. * * Read a byte from the control socket of the controllable @set. - * This function is mostly useful for timer #GstPoll objects created with - * gst_poll_new_timer(). * - * Returns: %TRUE on success. %FALSE when @set is not controllable or when there - * was no byte to read. + * This function only works for timer #GstPoll objects created with + * gst_poll_new_timer(). * - * Since: 0.10.23 + * Returns: %TRUE on success. %FALSE when when there was no byte to read or + * reading the byte failed. If there was no byte to read, and only then, errno + * will contain EWOULDBLOCK or EAGAIN. For all other values of errno this always signals a + * critical error. */ gboolean gst_poll_read_control (GstPoll * set)