|
Packit Service |
963350 |
/* GStreamer
|
|
Packit Service |
963350 |
* Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
|
|
Packit Service |
963350 |
* Copyright (C) 2004 Wim Taymans <wim.taymans@gmail.com>
|
|
Packit Service |
963350 |
* Copyright (C) 2007 Peter Kjellerstedt <pkj@axis.com>
|
|
Packit Service |
963350 |
* Copyright (C) 2008 Ole André Vadla Ravnås <ole.andre.ravnas@tandberg.com>
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* gstpoll.c: File descriptor set
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* This library is free software; you can redistribute it and/or
|
|
Packit Service |
963350 |
* modify it under the terms of the GNU Library General Public
|
|
Packit Service |
963350 |
* License as published by the Free Software Foundation; either
|
|
Packit Service |
963350 |
* version 2 of the License, or (at your option) any later version.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* This library is distributed in the hope that it will be useful,
|
|
Packit Service |
963350 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
963350 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
963350 |
* Library General Public License for more details.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* You should have received a copy of the GNU Library General Public
|
|
Packit Service |
963350 |
* License along with this library; if not, write to the
|
|
Packit Service |
963350 |
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
Packit Service |
963350 |
* Boston, MA 02110-1301, USA.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* SECTION:gstpoll
|
|
Packit Service |
963350 |
* @title: GstPoll
|
|
Packit Service |
963350 |
* @short_description: Keep track of file descriptors and make it possible
|
|
Packit Service |
963350 |
* to wait on them in a cancellable way
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* A #GstPoll keeps track of file descriptors much like fd_set (used with
|
|
Packit Service |
963350 |
* select()) or a struct pollfd array (used with poll()). Once created with
|
|
Packit Service |
963350 |
* gst_poll_new(), the set can be used to wait for file descriptors to be
|
|
Packit Service |
963350 |
* readable and/or writable. It is possible to make this wait be controlled
|
|
Packit Service |
963350 |
* by specifying %TRUE for the @controllable flag when creating the set (or
|
|
Packit Service |
963350 |
* later calling gst_poll_set_controllable()).
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* New file descriptors are added to the set using gst_poll_add_fd(), and
|
|
Packit Service |
963350 |
* removed using gst_poll_remove_fd(). Controlling which file descriptors
|
|
Packit Service |
963350 |
* should be waited for to become readable and/or writable are done using
|
|
Packit Service |
963350 |
* gst_poll_fd_ctl_read() and gst_poll_fd_ctl_write().
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Use gst_poll_wait() to wait for the file descriptors to actually become
|
|
Packit Service |
963350 |
* readable and/or writable, or to timeout if no file descriptor is available
|
|
Packit Service |
963350 |
* in time. The wait can be controlled by calling gst_poll_restart() and
|
|
Packit Service |
963350 |
* gst_poll_set_flushing().
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Once the file descriptor set has been waited for, one can use
|
|
Packit Service |
963350 |
* gst_poll_fd_has_closed() to see if the file descriptor has been closed,
|
|
Packit Service |
963350 |
* gst_poll_fd_has_error() to see if it has generated an error,
|
|
Packit Service |
963350 |
* gst_poll_fd_can_read() to see if it is possible to read from the file
|
|
Packit Service |
963350 |
* descriptor, and gst_poll_fd_can_write() to see if it is possible to
|
|
Packit Service |
963350 |
* write to it.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#ifdef HAVE_CONFIG_H
|
|
Packit Service |
963350 |
#include "config.h"
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#include "gst_private.h"
|
|
Packit Service |
963350 |
#include "glib-compat-private.h"
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#include <sys/types.h>
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#ifdef HAVE_UNISTD_H
|
|
Packit Service |
963350 |
#include <unistd.h>
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#include <errno.h>
|
|
Packit Service |
963350 |
#include <fcntl.h>
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#include <glib.h>
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#ifdef G_OS_WIN32
|
|
Packit Service |
963350 |
#include <winsock2.h>
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
#define _GNU_SOURCE 1
|
|
Packit Service |
963350 |
#ifdef HAVE_SYS_POLL_H
|
|
Packit Service |
963350 |
#include <sys/poll.h>
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
#ifdef HAVE_POLL_H
|
|
Packit Service |
963350 |
#include <poll.h>
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
#include <sys/time.h>
|
|
Packit Service |
963350 |
#include <sys/socket.h>
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#ifdef G_OS_WIN32
|
|
Packit Service |
963350 |
# ifndef EWOULDBLOCK
|
|
Packit Service |
963350 |
# define EWOULDBLOCK EAGAIN /* This is just to placate gcc */
|
|
Packit Service |
963350 |
# endif
|
|
Packit Service |
963350 |
#endif /* G_OS_WIN32 */
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* OS/X needs this because of bad headers */
|
|
Packit Service |
963350 |
#include <string.h>
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* The poll() emulation on OS/X doesn't handle fds=NULL, nfds=0,
|
|
Packit Service |
963350 |
* so we prefer our own poll emulation.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
#if defined(BROKEN_POLL)
|
|
Packit Service |
963350 |
#undef HAVE_POLL
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#include "gstpoll.h"
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#define GST_CAT_DEFAULT GST_CAT_POLL
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#ifdef G_OS_WIN32
|
|
Packit Service |
963350 |
typedef struct _WinsockFd WinsockFd;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
struct _WinsockFd
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gint fd;
|
|
Packit Service |
963350 |
glong event_mask;
|
|
Packit Service |
963350 |
WSANETWORKEVENTS events;
|
|
Packit Service |
963350 |
glong ignored_event_mask;
|
|
Packit Service |
963350 |
};
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
typedef enum
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
GST_POLL_MODE_AUTO,
|
|
Packit Service |
963350 |
GST_POLL_MODE_SELECT,
|
|
Packit Service |
963350 |
GST_POLL_MODE_PSELECT,
|
|
Packit Service |
963350 |
GST_POLL_MODE_POLL,
|
|
Packit Service |
963350 |
GST_POLL_MODE_PPOLL,
|
|
Packit Service |
963350 |
GST_POLL_MODE_WINDOWS
|
|
Packit Service |
963350 |
} GstPollMode;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
struct _GstPoll
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
GstPollMode mode;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
GMutex lock;
|
|
Packit Service |
963350 |
/* array of fds, always written to and read from with lock */
|
|
Packit Service |
963350 |
GArray *fds;
|
|
Packit Service |
963350 |
/* array of active fds, only written to from the waiting thread with the
|
|
Packit Service |
963350 |
* lock and read from with the lock or without the lock from the waiting
|
|
Packit Service |
963350 |
* thread */
|
|
Packit Service |
963350 |
GArray *active_fds;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
GstPollFD control_read_fd;
|
|
Packit Service |
963350 |
GstPollFD control_write_fd;
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
GArray *active_fds_ignored;
|
|
Packit Service |
963350 |
GArray *events;
|
|
Packit Service |
963350 |
GArray *active_events;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
HANDLE wakeup_event;
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
gboolean controllable;
|
|
Packit Service |
963350 |
volatile gint waiting;
|
|
Packit Service |
963350 |
volatile gint control_pending;
|
|
Packit Service |
963350 |
volatile gint flushing;
|
|
Packit Service |
963350 |
gboolean timer;
|
|
Packit Service |
963350 |
volatile gint rebuild;
|
|
Packit Service |
963350 |
};
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static gboolean gst_poll_fd_ctl_read_unlocked (GstPoll * set, GstPollFD * fd,
|
|
Packit Service |
963350 |
gboolean active);
|
|
Packit Service |
963350 |
static gboolean gst_poll_add_fd_unlocked (GstPoll * set, GstPollFD * fd);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#define IS_FLUSHING(s) (g_atomic_int_get(&(s)->flushing))
|
|
Packit Service |
963350 |
#define SET_FLUSHING(s,val) (g_atomic_int_set(&(s)->flushing, (val)))
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#define INC_WAITING(s) (g_atomic_int_add(&(s)->waiting, 1))
|
|
Packit Service |
963350 |
#define DEC_WAITING(s) (g_atomic_int_add(&(s)->waiting, -1))
|
|
Packit Service |
963350 |
#define GET_WAITING(s) (g_atomic_int_get(&(s)->waiting))
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#define TEST_REBUILD(s) (g_atomic_int_compare_and_exchange(&(s)->rebuild, 1, 0))
|
|
Packit Service |
963350 |
#define MARK_REBUILD(s) (g_atomic_int_set(&(s)->rebuild, 1))
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static gboolean
|
|
Packit Service |
963350 |
wake_event (GstPoll * set)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
ssize_t num_written;
|
|
Packit Service |
963350 |
while ((num_written = write (set->control_write_fd.fd, "W", 1)) != 1) {
|
|
Packit Service |
963350 |
if (num_written == -1 && errno != EAGAIN && errno != EINTR) {
|
|
Packit Service |
963350 |
g_critical ("%p: failed to wake event: %s", set, strerror (errno));
|
|
Packit Service |
963350 |
return FALSE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
return TRUE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static gboolean
|
|
Packit Service |
963350 |
release_event (GstPoll * set)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gchar buf[1] = { '\0' };
|
|
Packit Service |
963350 |
ssize_t num_read;
|
|
Packit Service |
963350 |
while ((num_read = read (set->control_read_fd.fd, buf, 1)) != 1) {
|
|
Packit Service |
963350 |
if (num_read == -1 && errno != EAGAIN && errno != EINTR) {
|
|
Packit Service |
963350 |
g_critical ("%p: failed to release event: %s", set, strerror (errno));
|
|
Packit Service |
963350 |
return FALSE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
return TRUE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static void
|
|
Packit Service |
963350 |
format_last_error (gchar * buf, size_t buf_len)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM;
|
|
Packit Service |
963350 |
LPCVOID src = NULL;
|
|
Packit Service |
963350 |
DWORD lang = 0;
|
|
Packit Service |
963350 |
DWORD id;
|
|
Packit Service |
963350 |
id = GetLastError ();
|
|
Packit Service |
963350 |
FormatMessage (flags, src, id, lang, buf, (DWORD) buf_len, NULL);
|
|
Packit Service |
963350 |
SetLastError (id);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static gboolean
|
|
Packit Service |
963350 |
wake_event (GstPoll * set)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
SetLastError (0);
|
|
Packit Service |
963350 |
errno = 0;
|
|
Packit Service |
963350 |
if (!SetEvent (set->wakeup_event)) {
|
|
Packit Service |
963350 |
gchar msg[1024] = "<unknown>";
|
|
Packit Service |
963350 |
format_last_error (msg, sizeof (msg));
|
|
Packit Service |
963350 |
g_critical ("%p: failed to set wakup_event: %s", set, msg);
|
|
Packit Service |
963350 |
errno = EBADF;
|
|
Packit Service |
963350 |
return FALSE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return TRUE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static gboolean
|
|
Packit Service |
963350 |
release_event (GstPoll * set)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
DWORD status;
|
|
Packit Service |
963350 |
SetLastError (0);
|
|
Packit Service |
963350 |
errno = 0;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
status = WaitForSingleObject (set->wakeup_event, INFINITE);
|
|
Packit Service |
963350 |
if (status) {
|
|
Packit Service |
963350 |
const gchar *reason = "unknown";
|
|
Packit Service |
963350 |
gchar msg[1024] = "<unknown>";
|
|
Packit Service |
963350 |
switch (status) {
|
|
Packit Service |
963350 |
case WAIT_ABANDONED:
|
|
Packit Service |
963350 |
reason = "WAIT_ABANDONED";
|
|
Packit Service |
963350 |
break;
|
|
Packit Service |
963350 |
case WAIT_TIMEOUT:
|
|
Packit Service |
963350 |
reason = "WAIT_TIMEOUT";
|
|
Packit Service |
963350 |
break;
|
|
Packit Service |
963350 |
case WAIT_FAILED:
|
|
Packit Service |
963350 |
format_last_error (msg, sizeof (msg));
|
|
Packit Service |
963350 |
reason = msg;
|
|
Packit Service |
963350 |
break;
|
|
Packit Service |
963350 |
default:
|
|
Packit Service |
963350 |
reason = "other";
|
|
Packit Service |
963350 |
break;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
g_critical ("%p: failed to block on wakup_event: %s", set, reason);
|
|
Packit Service |
963350 |
errno = EBADF;
|
|
Packit Service |
963350 |
return FALSE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (!ResetEvent (set->wakeup_event)) {
|
|
Packit Service |
963350 |
gchar msg[1024] = "<unknown>";
|
|
Packit Service |
963350 |
format_last_error (msg, sizeof (msg));
|
|
Packit Service |
963350 |
g_critical ("%p: failed to reset wakup_event: %s", set, msg);
|
|
Packit Service |
963350 |
errno = EBADF;
|
|
Packit Service |
963350 |
return FALSE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return TRUE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* the poll/select call is also performed on a control socket, that way
|
|
Packit Service |
963350 |
* we can send special commands to control it */
|
|
Packit Service |
963350 |
static inline gboolean
|
|
Packit Service |
963350 |
raise_wakeup (GstPoll * set)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gboolean result = TRUE;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* makes testing control_pending and WAKE_EVENT() atomic. */
|
|
Packit Service |
963350 |
g_mutex_lock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (set->control_pending == 0) {
|
|
Packit Service |
963350 |
/* raise when nothing pending */
|
|
Packit Service |
963350 |
GST_LOG ("%p: raise", set);
|
|
Packit Service |
963350 |
result = wake_event (set);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (result) {
|
|
Packit Service |
963350 |
set->control_pending++;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_unlock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return result;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static inline gboolean
|
|
Packit Service |
963350 |
release_wakeup (GstPoll * set)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gboolean result = FALSE;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* makes testing/modifying control_pending and RELEASE_EVENT() atomic. */
|
|
Packit Service |
963350 |
g_mutex_lock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (set->control_pending > 0) {
|
|
Packit Service |
963350 |
/* release, only if this was the last pending. */
|
|
Packit Service |
963350 |
if (set->control_pending == 1) {
|
|
Packit Service |
963350 |
GST_LOG ("%p: release", set);
|
|
Packit Service |
963350 |
result = release_event (set);
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
result = TRUE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (result) {
|
|
Packit Service |
963350 |
set->control_pending--;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
errno = EWOULDBLOCK;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_unlock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return result;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static inline gint
|
|
Packit Service |
963350 |
release_all_wakeup (GstPoll * set)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gint old;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* makes testing control_pending and RELEASE_EVENT() atomic. */
|
|
Packit Service |
963350 |
g_mutex_lock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if ((old = set->control_pending) > 0) {
|
|
Packit Service |
963350 |
GST_LOG ("%p: releasing %d", set, old);
|
|
Packit Service |
963350 |
if (release_event (set)) {
|
|
Packit Service |
963350 |
set->control_pending = 0;
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
old = 0;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_unlock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return old;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static gint
|
|
Packit Service |
963350 |
find_index (GArray * array, GstPollFD * fd)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
struct pollfd *ifd;
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
WinsockFd *ifd;
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
guint i;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* start by assuming the index found in the fd is still valid */
|
|
Packit Service |
963350 |
if (fd->idx >= 0 && fd->idx < array->len) {
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
ifd = &g_array_index (array, struct pollfd, fd->idx);
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
ifd = &g_array_index (array, WinsockFd, fd->idx);
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (ifd->fd == fd->fd) {
|
|
Packit Service |
963350 |
return fd->idx;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* the pollfd array has changed and we need to lookup the fd again */
|
|
Packit Service |
963350 |
for (i = 0; i < array->len; i++) {
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
ifd = &g_array_index (array, struct pollfd, i);
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
ifd = &g_array_index (array, WinsockFd, i);
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (ifd->fd == fd->fd) {
|
|
Packit Service |
963350 |
fd->idx = (gint) i;
|
|
Packit Service |
963350 |
return fd->idx;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
fd->idx = -1;
|
|
Packit Service |
963350 |
return fd->idx;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#if !defined(HAVE_PPOLL) && defined(HAVE_POLL)
|
|
Packit Service |
963350 |
/* check if all file descriptors will fit in an fd_set */
|
|
Packit Service |
963350 |
static gboolean
|
|
Packit Service |
963350 |
selectable_fds (GstPoll * set)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
guint i;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_lock (&set->lock);
|
|
Packit Service |
963350 |
for (i = 0; i < set->fds->len; i++) {
|
|
Packit Service |
963350 |
struct pollfd *pfd = &g_array_index (set->fds, struct pollfd, i);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (pfd->fd >= FD_SETSIZE)
|
|
Packit Service |
963350 |
goto too_many;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
g_mutex_unlock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return TRUE;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
too_many:
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
g_mutex_unlock (&set->lock);
|
|
Packit Service |
963350 |
return FALSE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* check if the timeout will convert to a timeout value used for poll()
|
|
Packit Service |
963350 |
* without a loss of precision
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
static gboolean
|
|
Packit Service |
963350 |
pollable_timeout (GstClockTime timeout)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
if (timeout == GST_CLOCK_TIME_NONE)
|
|
Packit Service |
963350 |
return TRUE;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* not a nice multiple of milliseconds */
|
|
Packit Service |
963350 |
if (timeout % 1000000)
|
|
Packit Service |
963350 |
return FALSE;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return TRUE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static GstPollMode
|
|
Packit Service |
963350 |
choose_mode (GstPoll * set, GstClockTime timeout)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
GstPollMode mode;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (set->mode == GST_POLL_MODE_AUTO) {
|
|
Packit Service |
963350 |
#ifdef HAVE_PPOLL
|
|
Packit Service |
963350 |
mode = GST_POLL_MODE_PPOLL;
|
|
Packit Service |
963350 |
#elif defined(HAVE_POLL)
|
|
Packit Service |
963350 |
if (!selectable_fds (set) || pollable_timeout (timeout)) {
|
|
Packit Service |
963350 |
mode = GST_POLL_MODE_POLL;
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
#ifdef HAVE_PSELECT
|
|
Packit Service |
963350 |
mode = GST_POLL_MODE_PSELECT;
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
mode = GST_POLL_MODE_SELECT;
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
#elif defined(HAVE_PSELECT)
|
|
Packit Service |
963350 |
mode = GST_POLL_MODE_PSELECT;
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
mode = GST_POLL_MODE_SELECT;
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
mode = set->mode;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
return mode;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
static gint
|
|
Packit Service |
963350 |
pollfd_to_fd_set (GstPoll * set, fd_set * readfds, fd_set * writefds,
|
|
Packit Service |
963350 |
fd_set * errorfds)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gint max_fd = -1;
|
|
Packit Service |
963350 |
guint i;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
FD_ZERO (readfds);
|
|
Packit Service |
963350 |
FD_ZERO (writefds);
|
|
Packit Service |
963350 |
FD_ZERO (errorfds);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_lock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
for (i = 0; i < set->active_fds->len; i++) {
|
|
Packit Service |
963350 |
struct pollfd *pfd = &g_array_index (set->fds, struct pollfd, i);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (pfd->fd < FD_SETSIZE) {
|
|
Packit Service |
963350 |
if (pfd->events & POLLIN)
|
|
Packit Service |
963350 |
FD_SET (pfd->fd, readfds);
|
|
Packit Service |
963350 |
if (pfd->events & POLLOUT)
|
|
Packit Service |
963350 |
FD_SET (pfd->fd, writefds);
|
|
Packit Service |
963350 |
if (pfd->events)
|
|
Packit Service |
963350 |
FD_SET (pfd->fd, errorfds);
|
|
Packit Service |
963350 |
if (pfd->fd > max_fd && (pfd->events & (POLLIN | POLLOUT)))
|
|
Packit Service |
963350 |
max_fd = pfd->fd;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_unlock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return max_fd;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static void
|
|
Packit Service |
963350 |
fd_set_to_pollfd (GstPoll * set, fd_set * readfds, fd_set * writefds,
|
|
Packit Service |
963350 |
fd_set * errorfds)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
guint i;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_lock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
for (i = 0; i < set->active_fds->len; i++) {
|
|
Packit Service |
963350 |
struct pollfd *pfd = &g_array_index (set->active_fds, struct pollfd, i);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (pfd->fd < FD_SETSIZE) {
|
|
Packit Service |
963350 |
pfd->revents = 0;
|
|
Packit Service |
963350 |
if (FD_ISSET (pfd->fd, readfds))
|
|
Packit Service |
963350 |
pfd->revents |= POLLIN;
|
|
Packit Service |
963350 |
if (FD_ISSET (pfd->fd, writefds))
|
|
Packit Service |
963350 |
pfd->revents |= POLLOUT;
|
|
Packit Service |
963350 |
if (FD_ISSET (pfd->fd, errorfds))
|
|
Packit Service |
963350 |
pfd->revents |= POLLERR;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_unlock (&set->lock);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
#else /* G_OS_WIN32 */
|
|
Packit Service |
963350 |
/*
|
|
Packit Service |
963350 |
* Translate errors thrown by the Winsock API used by GstPoll:
|
|
Packit Service |
963350 |
* WSAEventSelect, WSAWaitForMultipleEvents and WSAEnumNetworkEvents
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
static gint
|
|
Packit Service |
963350 |
gst_poll_winsock_error_to_errno (DWORD last_error)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
switch (last_error) {
|
|
Packit Service |
963350 |
case WSA_INVALID_HANDLE:
|
|
Packit Service |
963350 |
case WSAEINVAL:
|
|
Packit Service |
963350 |
case WSAENOTSOCK:
|
|
Packit Service |
963350 |
return EBADF;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
case WSA_NOT_ENOUGH_MEMORY:
|
|
Packit Service |
963350 |
return ENOMEM;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/*
|
|
Packit Service |
963350 |
* Anything else, including:
|
|
Packit Service |
963350 |
* WSA_INVALID_PARAMETER, WSAEFAULT, WSAEINPROGRESS, WSAENETDOWN,
|
|
Packit Service |
963350 |
* WSANOTINITIALISED
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
default:
|
|
Packit Service |
963350 |
return EINVAL;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static void
|
|
Packit Service |
963350 |
gst_poll_free_winsock_event (GstPoll * set, gint idx)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
WinsockFd *wfd = &g_array_index (set->fds, WinsockFd, idx);
|
|
Packit Service |
963350 |
HANDLE event = g_array_index (set->events, HANDLE, idx);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
WSAEventSelect (wfd->fd, event, 0);
|
|
Packit Service |
963350 |
CloseHandle (event);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static void
|
|
Packit Service |
963350 |
gst_poll_update_winsock_event_mask (GstPoll * set, gint idx, glong flags,
|
|
Packit Service |
963350 |
gboolean active)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
WinsockFd *wfd;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
wfd = &g_array_index (set->fds, WinsockFd, idx);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (active)
|
|
Packit Service |
963350 |
wfd->event_mask |= flags;
|
|
Packit Service |
963350 |
else
|
|
Packit Service |
963350 |
wfd->event_mask &= ~flags;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* reset ignored state if the new mask doesn't overlap at all */
|
|
Packit Service |
963350 |
if ((wfd->ignored_event_mask & wfd->event_mask) == 0)
|
|
Packit Service |
963350 |
wfd->ignored_event_mask = 0;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static gboolean
|
|
Packit Service |
963350 |
gst_poll_prepare_winsock_active_sets (GstPoll * set)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
guint i;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_array_set_size (set->active_fds, 0);
|
|
Packit Service |
963350 |
g_array_set_size (set->active_fds_ignored, 0);
|
|
Packit Service |
963350 |
g_array_set_size (set->active_events, 0);
|
|
Packit Service |
963350 |
g_array_append_val (set->active_events, set->wakeup_event);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
for (i = 0; i < set->fds->len; i++) {
|
|
Packit Service |
963350 |
WinsockFd *wfd = &g_array_index (set->fds, WinsockFd, i);
|
|
Packit Service |
963350 |
HANDLE event = g_array_index (set->events, HANDLE, i);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (wfd->ignored_event_mask == 0) {
|
|
Packit Service |
963350 |
gint ret;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_array_append_val (set->active_fds, *wfd);
|
|
Packit Service |
963350 |
g_array_append_val (set->active_events, event);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
ret = WSAEventSelect (wfd->fd, event, wfd->event_mask);
|
|
Packit Service |
963350 |
if (G_UNLIKELY (ret != 0)) {
|
|
Packit Service |
963350 |
errno = gst_poll_winsock_error_to_errno (WSAGetLastError ());
|
|
Packit Service |
963350 |
return FALSE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
g_array_append_val (set->active_fds_ignored, wfd);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return TRUE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static gint
|
|
Packit Service |
963350 |
gst_poll_collect_winsock_events (GstPoll * set)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gint res, i;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/*
|
|
Packit Service |
963350 |
* We need to check which events are signaled, and call
|
|
Packit Service |
963350 |
* WSAEnumNetworkEvents for those that are, which resets
|
|
Packit Service |
963350 |
* the event and clears the internal network event records.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
res = 0;
|
|
Packit Service |
963350 |
for (i = 0; i < set->active_fds->len; i++) {
|
|
Packit Service |
963350 |
WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, i);
|
|
Packit Service |
963350 |
HANDLE event = g_array_index (set->active_events, HANDLE, i + 1);
|
|
Packit Service |
963350 |
DWORD wait_ret;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
wait_ret = WaitForSingleObject (event, 0);
|
|
Packit Service |
963350 |
if (wait_ret == WAIT_OBJECT_0) {
|
|
Packit Service |
963350 |
gint enum_ret = WSAEnumNetworkEvents (wfd->fd, event, &wfd->events);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (G_UNLIKELY (enum_ret != 0)) {
|
|
Packit Service |
963350 |
res = -1;
|
|
Packit Service |
963350 |
errno = gst_poll_winsock_error_to_errno (WSAGetLastError ());
|
|
Packit Service |
963350 |
break;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
res++;
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
/* clear any previously stored result */
|
|
Packit Service |
963350 |
memset (&wfd->events, 0, sizeof (wfd->events));
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* If all went well we also need to reset the ignored fds. */
|
|
Packit Service |
963350 |
if (res >= 0) {
|
|
Packit Service |
963350 |
res += set->active_fds_ignored->len;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
for (i = 0; i < set->active_fds_ignored->len; i++) {
|
|
Packit Service |
963350 |
WinsockFd *wfd = g_array_index (set->active_fds_ignored, WinsockFd *, i);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
wfd->ignored_event_mask = 0;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_array_set_size (set->active_fds_ignored, 0);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return res;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_new: (skip)
|
|
Packit Service |
963350 |
* @controllable: whether it should be possible to control a wait.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Create a new file descriptor set. If @controllable, it
|
|
Packit Service |
963350 |
* is possible to restart or flush a call to gst_poll_wait() with
|
|
Packit Service |
963350 |
* gst_poll_restart() and gst_poll_set_flushing() respectively.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Free-function: gst_poll_free
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Returns: (transfer full) (nullable): a new #GstPoll, or %NULL in
|
|
Packit Service |
963350 |
* case of an error. Free with gst_poll_free().
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
GstPoll *
|
|
Packit Service |
963350 |
gst_poll_new (gboolean controllable)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
GstPoll *nset;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
nset = g_slice_new0 (GstPoll);
|
|
Packit Service |
963350 |
GST_DEBUG ("%p: new controllable : %d", nset, controllable);
|
|
Packit Service |
963350 |
g_mutex_init (&nset->lock);
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
nset->mode = GST_POLL_MODE_AUTO;
|
|
Packit Service |
963350 |
nset->fds = g_array_new (FALSE, FALSE, sizeof (struct pollfd));
|
|
Packit Service |
963350 |
nset->active_fds = g_array_new (FALSE, FALSE, sizeof (struct pollfd));
|
|
Packit Service |
963350 |
nset->control_read_fd.fd = -1;
|
|
Packit Service |
963350 |
nset->control_write_fd.fd = -1;
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gint control_sock[2];
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (socketpair (PF_UNIX, SOCK_STREAM, 0, control_sock) < 0)
|
|
Packit Service |
963350 |
goto no_socket_pair;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
nset->control_read_fd.fd = control_sock[0];
|
|
Packit Service |
963350 |
nset->control_write_fd.fd = control_sock[1];
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
gst_poll_add_fd_unlocked (nset, &nset->control_read_fd);
|
|
Packit Service |
963350 |
gst_poll_fd_ctl_read_unlocked (nset, &nset->control_read_fd, TRUE);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
nset->mode = GST_POLL_MODE_WINDOWS;
|
|
Packit Service |
963350 |
nset->fds = g_array_new (FALSE, FALSE, sizeof (WinsockFd));
|
|
Packit Service |
963350 |
nset->active_fds = g_array_new (FALSE, FALSE, sizeof (WinsockFd));
|
|
Packit Service |
963350 |
nset->active_fds_ignored = g_array_new (FALSE, FALSE, sizeof (WinsockFd *));
|
|
Packit Service |
963350 |
nset->events = g_array_new (FALSE, FALSE, sizeof (HANDLE));
|
|
Packit Service |
963350 |
nset->active_events = g_array_new (FALSE, FALSE, sizeof (HANDLE));
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
nset->wakeup_event = CreateEvent (NULL, TRUE, FALSE, NULL);
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* ensure (re)build, though already sneakily set in non-windows case */
|
|
Packit Service |
963350 |
MARK_REBUILD (nset);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
nset->controllable = controllable;
|
|
Packit Service |
963350 |
nset->control_pending = 0;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return nset;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* ERRORS */
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
no_socket_pair:
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
GST_WARNING ("%p: can't create socket pair !", nset);
|
|
Packit Service |
963350 |
gst_poll_free (nset);
|
|
Packit Service |
963350 |
return NULL;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_new_timer: (skip)
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Create a new poll object that can be used for scheduling cancellable
|
|
Packit Service |
963350 |
* timeouts.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* A timeout is performed with gst_poll_wait(). Multiple timeouts can be
|
|
Packit Service |
963350 |
* performed from different threads.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Free-function: gst_poll_free
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Returns: (transfer full) (nullable): a new #GstPoll, or %NULL in
|
|
Packit Service |
963350 |
* case of an error. Free with gst_poll_free().
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
GstPoll *
|
|
Packit Service |
963350 |
gst_poll_new_timer (void)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
GstPoll *poll;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* make a new controllable poll set */
|
|
Packit Service |
963350 |
if (!(poll = gst_poll_new (TRUE)))
|
|
Packit Service |
963350 |
goto done;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* we are a timer */
|
|
Packit Service |
963350 |
poll->timer = TRUE;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
done:
|
|
Packit Service |
963350 |
return poll;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_free:
|
|
Packit Service |
963350 |
* @set: (transfer full): a file descriptor set.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Free a file descriptor set.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
void
|
|
Packit Service |
963350 |
gst_poll_free (GstPoll * set)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
g_return_if_fail (set != NULL);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
GST_DEBUG ("%p: freeing", set);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
if (set->control_write_fd.fd >= 0)
|
|
Packit Service |
963350 |
close (set->control_write_fd.fd);
|
|
Packit Service |
963350 |
if (set->control_read_fd.fd >= 0)
|
|
Packit Service |
963350 |
close (set->control_read_fd.fd);
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
CloseHandle (set->wakeup_event);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
guint i;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
for (i = 0; i < set->events->len; i++)
|
|
Packit Service |
963350 |
gst_poll_free_winsock_event (set, i);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_array_free (set->active_events, TRUE);
|
|
Packit Service |
963350 |
g_array_free (set->events, TRUE);
|
|
Packit Service |
963350 |
g_array_free (set->active_fds_ignored, TRUE);
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_array_free (set->active_fds, TRUE);
|
|
Packit Service |
963350 |
g_array_free (set->fds, TRUE);
|
|
Packit Service |
963350 |
g_mutex_clear (&set->lock);
|
|
Packit Service |
963350 |
g_slice_free (GstPoll, set);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_get_read_gpollfd:
|
|
Packit Service |
963350 |
* @set: a #GstPoll
|
|
Packit Service |
963350 |
* @fd: a #GPollFD
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Get a GPollFD for the reading part of the control socket. This is useful when
|
|
Packit Service |
963350 |
* integrating with a GSource and GMainLoop.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
void
|
|
Packit Service |
963350 |
gst_poll_get_read_gpollfd (GstPoll * set, GPollFD * fd)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
g_return_if_fail (set != NULL);
|
|
Packit Service |
963350 |
g_return_if_fail (fd != NULL);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
fd->fd = set->control_read_fd.fd;
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
#if GLIB_SIZEOF_VOID_P == 8
|
|
Packit Service |
963350 |
fd->fd = (gint64) set->wakeup_event;
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
fd->fd = (gint) set->wakeup_event;
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
fd->events = G_IO_IN | G_IO_HUP | G_IO_ERR;
|
|
Packit Service |
963350 |
fd->revents = 0;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_fd_init:
|
|
Packit Service |
963350 |
* @fd: a #GstPollFD
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Initializes @fd. Alternatively you can initialize it with
|
|
Packit Service |
963350 |
* #GST_POLL_FD_INIT.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
void
|
|
Packit Service |
963350 |
gst_poll_fd_init (GstPollFD * fd)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
g_return_if_fail (fd != NULL);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
fd->fd = -1;
|
|
Packit Service |
963350 |
fd->idx = -1;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static gboolean
|
|
Packit Service |
963350 |
gst_poll_add_fd_unlocked (GstPoll * set, GstPollFD * fd)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gint idx;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
GST_DEBUG ("%p: fd (fd:%d, idx:%d)", set, fd->fd, fd->idx);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
idx = find_index (set->fds, fd);
|
|
Packit Service |
963350 |
if (idx < 0) {
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
struct pollfd nfd;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
nfd.fd = fd->fd;
|
|
Packit Service |
963350 |
nfd.events = POLLERR | POLLNVAL | POLLHUP;
|
|
Packit Service |
963350 |
nfd.revents = 0;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_array_append_val (set->fds, nfd);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
fd->idx = set->fds->len - 1;
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
WinsockFd wfd;
|
|
Packit Service |
963350 |
HANDLE event;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
wfd.fd = fd->fd;
|
|
Packit Service |
963350 |
wfd.event_mask = FD_CLOSE;
|
|
Packit Service |
963350 |
memset (&wfd.events, 0, sizeof (wfd.events));
|
|
Packit Service |
963350 |
wfd.ignored_event_mask = 0;
|
|
Packit Service |
963350 |
event = WSACreateEvent ();
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_array_append_val (set->fds, wfd);
|
|
Packit Service |
963350 |
g_array_append_val (set->events, event);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
fd->idx = set->fds->len - 1;
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
MARK_REBUILD (set);
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
GST_WARNING ("%p: fd already added !", set);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return TRUE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_add_fd:
|
|
Packit Service |
963350 |
* @set: a file descriptor set.
|
|
Packit Service |
963350 |
* @fd: a file descriptor.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Add a file descriptor to the file descriptor set.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Returns: %TRUE if the file descriptor was successfully added to the set.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
gboolean
|
|
Packit Service |
963350 |
gst_poll_add_fd (GstPoll * set, GstPollFD * fd)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gboolean ret;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_return_val_if_fail (set != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (fd != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (fd->fd >= 0, FALSE);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_lock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
ret = gst_poll_add_fd_unlocked (set, fd);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_unlock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return ret;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_remove_fd:
|
|
Packit Service |
963350 |
* @set: a file descriptor set.
|
|
Packit Service |
963350 |
* @fd: a file descriptor.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Remove a file descriptor from the file descriptor set.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Returns: %TRUE if the file descriptor was successfully removed from the set.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
gboolean
|
|
Packit Service |
963350 |
gst_poll_remove_fd (GstPoll * set, GstPollFD * fd)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gint idx;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_return_val_if_fail (set != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (fd != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (fd->fd >= 0, FALSE);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
GST_DEBUG ("%p: fd (fd:%d, idx:%d)", set, fd->fd, fd->idx);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_lock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* get the index, -1 is an fd that is not added */
|
|
Packit Service |
963350 |
idx = find_index (set->fds, fd);
|
|
Packit Service |
963350 |
if (idx >= 0) {
|
|
Packit Service |
963350 |
#ifdef G_OS_WIN32
|
|
Packit Service |
963350 |
gst_poll_free_winsock_event (set, idx);
|
|
Packit Service |
963350 |
g_array_remove_index_fast (set->events, idx);
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* remove the fd at index, we use _remove_index_fast, which copies the last
|
|
Packit Service |
963350 |
* element of the array to the freed index */
|
|
Packit Service |
963350 |
g_array_remove_index_fast (set->fds, idx);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* mark fd as removed by setting the index to -1 */
|
|
Packit Service |
963350 |
fd->idx = -1;
|
|
Packit Service |
963350 |
MARK_REBUILD (set);
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
GST_WARNING ("%p: couldn't find fd !", set);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_unlock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return idx >= 0;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_fd_ctl_write:
|
|
Packit Service |
963350 |
* @set: a file descriptor set.
|
|
Packit Service |
963350 |
* @fd: a file descriptor.
|
|
Packit Service |
963350 |
* @active: a new status.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Control whether the descriptor @fd in @set will be monitored for
|
|
Packit Service |
963350 |
* writability.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Returns: %TRUE if the descriptor was successfully updated.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
gboolean
|
|
Packit Service |
963350 |
gst_poll_fd_ctl_write (GstPoll * set, GstPollFD * fd, gboolean active)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gint idx;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_return_val_if_fail (set != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (fd != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (fd->fd >= 0, FALSE);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
GST_DEBUG ("%p: fd (fd:%d, idx:%d), active : %d", set,
|
|
Packit Service |
963350 |
fd->fd, fd->idx, active);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_lock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
idx = find_index (set->fds, fd);
|
|
Packit Service |
963350 |
if (idx >= 0) {
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
struct pollfd *pfd = &g_array_index (set->fds, struct pollfd, idx);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (active)
|
|
Packit Service |
963350 |
pfd->events |= POLLOUT;
|
|
Packit Service |
963350 |
else
|
|
Packit Service |
963350 |
pfd->events &= ~POLLOUT;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
GST_LOG ("%p: pfd->events now %d (POLLOUT:%d)", set, pfd->events, POLLOUT);
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
gst_poll_update_winsock_event_mask (set, idx, FD_WRITE | FD_CONNECT,
|
|
Packit Service |
963350 |
active);
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
MARK_REBUILD (set);
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
GST_WARNING ("%p: couldn't find fd !", set);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_unlock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return idx >= 0;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static gboolean
|
|
Packit Service |
963350 |
gst_poll_fd_ctl_read_unlocked (GstPoll * set, GstPollFD * fd, gboolean active)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gint idx;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
GST_DEBUG ("%p: fd (fd:%d, idx:%d), active : %d", set,
|
|
Packit Service |
963350 |
fd->fd, fd->idx, active);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
idx = find_index (set->fds, fd);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (idx >= 0) {
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
struct pollfd *pfd = &g_array_index (set->fds, struct pollfd, idx);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (active)
|
|
Packit Service |
963350 |
pfd->events |= (POLLIN | POLLPRI);
|
|
Packit Service |
963350 |
else
|
|
Packit Service |
963350 |
pfd->events &= ~(POLLIN | POLLPRI);
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
gst_poll_update_winsock_event_mask (set, idx, FD_READ | FD_ACCEPT, active);
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
MARK_REBUILD (set);
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
GST_WARNING ("%p: couldn't find fd !", set);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return idx >= 0;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_fd_ctl_read:
|
|
Packit Service |
963350 |
* @set: a file descriptor set.
|
|
Packit Service |
963350 |
* @fd: a file descriptor.
|
|
Packit Service |
963350 |
* @active: a new status.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Control whether the descriptor @fd in @set will be monitored for
|
|
Packit Service |
963350 |
* readability.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Returns: %TRUE if the descriptor was successfully updated.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
gboolean
|
|
Packit Service |
963350 |
gst_poll_fd_ctl_read (GstPoll * set, GstPollFD * fd, gboolean active)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gboolean ret;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_return_val_if_fail (set != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (fd != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (fd->fd >= 0, FALSE);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_lock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
ret = gst_poll_fd_ctl_read_unlocked (set, fd, active);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_unlock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return ret;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_fd_ignored:
|
|
Packit Service |
963350 |
* @set: a file descriptor set.
|
|
Packit Service |
963350 |
* @fd: a file descriptor.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Mark @fd as ignored so that the next call to gst_poll_wait() will yield
|
|
Packit Service |
963350 |
* the same result for @fd as last time. This function must be called if no
|
|
Packit Service |
963350 |
* operation (read/write/recv/send/etc.) will be performed on @fd before
|
|
Packit Service |
963350 |
* the next call to gst_poll_wait().
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* The reason why this is needed is because the underlying implementation
|
|
Packit Service |
963350 |
* might not allow querying the fd more than once between calls to one of
|
|
Packit Service |
963350 |
* the re-enabling operations.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
void
|
|
Packit Service |
963350 |
gst_poll_fd_ignored (GstPoll * set, GstPollFD * fd)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
#ifdef G_OS_WIN32
|
|
Packit Service |
963350 |
gint idx;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_return_if_fail (set != NULL);
|
|
Packit Service |
963350 |
g_return_if_fail (fd != NULL);
|
|
Packit Service |
963350 |
g_return_if_fail (fd->fd >= 0);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_lock (&set->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
idx = find_index (set->fds, fd);
|
|
Packit Service |
963350 |
if (idx >= 0) {
|
|
Packit Service |
963350 |
WinsockFd *wfd = &g_array_index (set->fds, WinsockFd, idx);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
wfd->ignored_event_mask = wfd->event_mask & (FD_READ | FD_WRITE);
|
|
Packit Service |
963350 |
MARK_REBUILD (set);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_unlock (&set->lock);
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_fd_has_closed:
|
|
Packit Service |
963350 |
* @set: a file descriptor set.
|
|
Packit Service |
963350 |
* @fd: a file descriptor.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Check if @fd in @set has closed the connection.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Returns: %TRUE if the connection was closed.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
gboolean
|
|
Packit Service |
963350 |
gst_poll_fd_has_closed (const GstPoll * set, GstPollFD * fd)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gboolean res = FALSE;
|
|
Packit Service |
963350 |
gint idx;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_return_val_if_fail (set != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (fd != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (fd->fd >= 0, FALSE);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_lock (&((GstPoll *) set)->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
idx = find_index (set->active_fds, fd);
|
|
Packit Service |
963350 |
if (idx >= 0) {
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
struct pollfd *pfd = &g_array_index (set->active_fds, struct pollfd, idx);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
res = (pfd->revents & POLLHUP) != 0;
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, idx);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
res = (wfd->events.lNetworkEvents & FD_CLOSE) != 0;
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
GST_WARNING ("%p: couldn't find fd !", set);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
g_mutex_unlock (&((GstPoll *) set)->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
GST_DEBUG ("%p: fd (fd:%d, idx:%d) %d", set, fd->fd, fd->idx, res);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return res;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_fd_has_error:
|
|
Packit Service |
963350 |
* @set: a file descriptor set.
|
|
Packit Service |
963350 |
* @fd: a file descriptor.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Check if @fd in @set has an error.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Returns: %TRUE if the descriptor has an error.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
gboolean
|
|
Packit Service |
963350 |
gst_poll_fd_has_error (const GstPoll * set, GstPollFD * fd)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gboolean res = FALSE;
|
|
Packit Service |
963350 |
gint idx;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_return_val_if_fail (set != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (fd != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (fd->fd >= 0, FALSE);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_lock (&((GstPoll *) set)->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
idx = find_index (set->active_fds, fd);
|
|
Packit Service |
963350 |
if (idx >= 0) {
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
struct pollfd *pfd = &g_array_index (set->active_fds, struct pollfd, idx);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
res = (pfd->revents & (POLLERR | POLLNVAL)) != 0;
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, idx);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
res = (wfd->events.iErrorCode[FD_CLOSE_BIT] != 0) ||
|
|
Packit Service |
963350 |
(wfd->events.iErrorCode[FD_READ_BIT] != 0) ||
|
|
Packit Service |
963350 |
(wfd->events.iErrorCode[FD_WRITE_BIT] != 0) ||
|
|
Packit Service |
963350 |
(wfd->events.iErrorCode[FD_ACCEPT_BIT] != 0) ||
|
|
Packit Service |
963350 |
(wfd->events.iErrorCode[FD_CONNECT_BIT] != 0);
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
GST_WARNING ("%p: couldn't find fd !", set);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
g_mutex_unlock (&((GstPoll *) set)->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
GST_DEBUG ("%p: fd (fd:%d, idx:%d) %d", set, fd->fd, fd->idx, res);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return res;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
static gboolean
|
|
Packit Service |
963350 |
gst_poll_fd_can_read_unlocked (const GstPoll * set, GstPollFD * fd)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gboolean res = FALSE;
|
|
Packit Service |
963350 |
gint idx;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
idx = find_index (set->active_fds, fd);
|
|
Packit Service |
963350 |
if (idx >= 0) {
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
struct pollfd *pfd = &g_array_index (set->active_fds, struct pollfd, idx);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
res = (pfd->revents & (POLLIN | POLLPRI)) != 0;
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, idx);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
res = (wfd->events.lNetworkEvents & (FD_READ | FD_ACCEPT)) != 0;
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
GST_WARNING ("%p: couldn't find fd !", set);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
GST_DEBUG ("%p: fd (fd:%d, idx:%d) %d", set, fd->fd, fd->idx, res);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return res;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_fd_can_read:
|
|
Packit Service |
963350 |
* @set: a file descriptor set.
|
|
Packit Service |
963350 |
* @fd: a file descriptor.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Check if @fd in @set has data to be read.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Returns: %TRUE if the descriptor has data to be read.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
gboolean
|
|
Packit Service |
963350 |
gst_poll_fd_can_read (const GstPoll * set, GstPollFD * fd)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gboolean res = FALSE;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_return_val_if_fail (set != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (fd != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (fd->fd >= 0, FALSE);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_lock (&((GstPoll *) set)->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
res = gst_poll_fd_can_read_unlocked (set, fd);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_unlock (&((GstPoll *) set)->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return res;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_fd_can_write:
|
|
Packit Service |
963350 |
* @set: a file descriptor set.
|
|
Packit Service |
963350 |
* @fd: a file descriptor.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Check if @fd in @set can be used for writing.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Returns: %TRUE if the descriptor can be used for writing.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
gboolean
|
|
Packit Service |
963350 |
gst_poll_fd_can_write (const GstPoll * set, GstPollFD * fd)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gboolean res = FALSE;
|
|
Packit Service |
963350 |
gint idx;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_return_val_if_fail (set != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (fd != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (fd->fd >= 0, FALSE);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_mutex_lock (&((GstPoll *) set)->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
idx = find_index (set->active_fds, fd);
|
|
Packit Service |
963350 |
if (idx >= 0) {
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
struct pollfd *pfd = &g_array_index (set->active_fds, struct pollfd, idx);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
res = (pfd->revents & POLLOUT) != 0;
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, idx);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
res = (wfd->events.lNetworkEvents & FD_WRITE) != 0;
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
GST_WARNING ("%p: couldn't find fd !", set);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
g_mutex_unlock (&((GstPoll *) set)->lock);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
GST_DEBUG ("%p: fd (fd:%d, idx:%d) %d", set, fd->fd, fd->idx, res);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return res;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_wait:
|
|
Packit Service |
963350 |
* @set: a #GstPoll.
|
|
Packit Service |
963350 |
* @timeout: a timeout in nanoseconds.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Wait for activity on the file descriptors in @set. This function waits up to
|
|
Packit Service |
963350 |
* the specified @timeout. A timeout of #GST_CLOCK_TIME_NONE waits forever.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* For #GstPoll objects created with gst_poll_new(), this function can only be
|
|
Packit Service |
963350 |
* called from a single thread at a time. If called from multiple threads,
|
|
Packit Service |
963350 |
* -1 will be returned with errno set to EPERM.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* This is not true for timer #GstPoll objects created with
|
|
Packit Service |
963350 |
* gst_poll_new_timer(), where it is allowed to have multiple threads waiting
|
|
Packit Service |
963350 |
* simultaneously.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Returns: The number of #GstPollFD in @set that have activity or 0 when no
|
|
Packit Service |
963350 |
* activity was detected after @timeout. If an error occurs, -1 is returned
|
|
Packit Service |
963350 |
* and errno is set.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
gint
|
|
Packit Service |
963350 |
gst_poll_wait (GstPoll * set, GstClockTime timeout)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gboolean restarting;
|
|
Packit Service |
963350 |
gboolean is_timer;
|
|
Packit Service |
963350 |
int res;
|
|
Packit Service |
963350 |
gint old_waiting;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_return_val_if_fail (set != NULL, -1);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
GST_DEBUG ("%p: timeout :%" GST_TIME_FORMAT, set, GST_TIME_ARGS (timeout));
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
is_timer = set->timer;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* add one more waiter */
|
|
Packit Service |
963350 |
old_waiting = INC_WAITING (set);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* we cannot wait from multiple threads unless we are a timer */
|
|
Packit Service |
963350 |
if (G_UNLIKELY (old_waiting > 0 && !is_timer))
|
|
Packit Service |
963350 |
goto already_waiting;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* flushing, exit immediately */
|
|
Packit Service |
963350 |
if (G_UNLIKELY (IS_FLUSHING (set)))
|
|
Packit Service |
963350 |
goto flushing;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
do {
|
|
Packit Service |
963350 |
GstPollMode mode;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
res = -1;
|
|
Packit Service |
963350 |
restarting = FALSE;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
mode = choose_mode (set, timeout);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (TEST_REBUILD (set)) {
|
|
Packit Service |
963350 |
g_mutex_lock (&set->lock);
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
g_array_set_size (set->active_fds, set->fds->len);
|
|
Packit Service |
963350 |
memcpy (set->active_fds->data, set->fds->data,
|
|
Packit Service |
963350 |
set->fds->len * sizeof (struct pollfd));
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
if (!gst_poll_prepare_winsock_active_sets (set))
|
|
Packit Service |
963350 |
goto winsock_error;
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
g_mutex_unlock (&set->lock);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
switch (mode) {
|
|
Packit Service |
963350 |
case GST_POLL_MODE_AUTO:
|
|
Packit Service |
963350 |
g_assert_not_reached ();
|
|
Packit Service |
963350 |
break;
|
|
Packit Service |
963350 |
case GST_POLL_MODE_PPOLL:
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
#ifdef HAVE_PPOLL
|
|
Packit Service |
963350 |
struct timespec ts;
|
|
Packit Service |
963350 |
struct timespec *tsptr;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (timeout != GST_CLOCK_TIME_NONE) {
|
|
Packit Service |
963350 |
GST_TIME_TO_TIMESPEC (timeout, ts);
|
|
Packit Service |
963350 |
tsptr = &ts;
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
tsptr = NULL;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
res =
|
|
Packit Service |
963350 |
ppoll ((struct pollfd *) set->active_fds->data,
|
|
Packit Service |
963350 |
set->active_fds->len, tsptr, NULL);
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
g_assert_not_reached ();
|
|
Packit Service |
963350 |
errno = ENOSYS;
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
break;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
case GST_POLL_MODE_POLL:
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
#ifdef HAVE_POLL
|
|
Packit Service |
963350 |
gint t;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (timeout != GST_CLOCK_TIME_NONE) {
|
|
Packit Service |
963350 |
t = GST_TIME_AS_MSECONDS (timeout);
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
t = -1;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
res =
|
|
Packit Service |
963350 |
poll ((struct pollfd *) set->active_fds->data,
|
|
Packit Service |
963350 |
set->active_fds->len, t);
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
g_assert_not_reached ();
|
|
Packit Service |
963350 |
errno = ENOSYS;
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
break;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
case GST_POLL_MODE_PSELECT:
|
|
Packit Service |
963350 |
#ifndef HAVE_PSELECT
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
g_assert_not_reached ();
|
|
Packit Service |
963350 |
errno = ENOSYS;
|
|
Packit Service |
963350 |
break;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
case GST_POLL_MODE_SELECT:
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
#ifndef G_OS_WIN32
|
|
Packit Service |
963350 |
fd_set readfds;
|
|
Packit Service |
963350 |
fd_set writefds;
|
|
Packit Service |
963350 |
fd_set errorfds;
|
|
Packit Service |
963350 |
gint max_fd;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
max_fd = pollfd_to_fd_set (set, &readfds, &writefds, &errorfds);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (mode == GST_POLL_MODE_SELECT) {
|
|
Packit Service |
963350 |
struct timeval tv;
|
|
Packit Service |
963350 |
struct timeval *tvptr;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (timeout != GST_CLOCK_TIME_NONE) {
|
|
Packit Service |
963350 |
GST_TIME_TO_TIMEVAL (timeout, tv);
|
|
Packit Service |
963350 |
tvptr = &tv;
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
tvptr = NULL;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
GST_DEBUG ("%p: Calling select", set);
|
|
Packit Service |
963350 |
res = select (max_fd + 1, &readfds, &writefds, &errorfds, tvptr);
|
|
Packit Service |
963350 |
GST_DEBUG ("%p: After select, res:%d", set, res);
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
#ifdef HAVE_PSELECT
|
|
Packit Service |
963350 |
struct timespec ts;
|
|
Packit Service |
963350 |
struct timespec *tsptr;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (timeout != GST_CLOCK_TIME_NONE) {
|
|
Packit Service |
963350 |
GST_TIME_TO_TIMESPEC (timeout, ts);
|
|
Packit Service |
963350 |
tsptr = &ts;
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
tsptr = NULL;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
GST_DEBUG ("%p: Calling pselect", set);
|
|
Packit Service |
963350 |
res =
|
|
Packit Service |
963350 |
pselect (max_fd + 1, &readfds, &writefds, &errorfds, tsptr, NULL);
|
|
Packit Service |
963350 |
GST_DEBUG ("%p: After pselect, res:%d", set, res);
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (res >= 0) {
|
|
Packit Service |
963350 |
fd_set_to_pollfd (set, &readfds, &writefds, &errorfds);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
#else /* G_OS_WIN32 */
|
|
Packit Service |
963350 |
g_assert_not_reached ();
|
|
Packit Service |
963350 |
errno = ENOSYS;
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
break;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
case GST_POLL_MODE_WINDOWS:
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
#ifdef G_OS_WIN32
|
|
Packit Service |
963350 |
gint ignore_count = set->active_fds_ignored->len;
|
|
Packit Service |
963350 |
DWORD t, wait_ret;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (G_LIKELY (ignore_count == 0)) {
|
|
Packit Service |
963350 |
if (timeout != GST_CLOCK_TIME_NONE)
|
|
Packit Service |
963350 |
t = GST_TIME_AS_MSECONDS (timeout);
|
|
Packit Service |
963350 |
else
|
|
Packit Service |
963350 |
t = INFINITE;
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
/* already one or more ignored fds, so we quickly sweep the others */
|
|
Packit Service |
963350 |
t = 0;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (set->active_events->len != 0) {
|
|
Packit Service |
963350 |
wait_ret = WSAWaitForMultipleEvents (set->active_events->len,
|
|
Packit Service |
963350 |
(HANDLE *) set->active_events->data, FALSE, t, FALSE);
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
wait_ret = WSA_WAIT_FAILED;
|
|
Packit Service |
963350 |
WSASetLastError (WSA_INVALID_PARAMETER);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (ignore_count == 0 && wait_ret == WSA_WAIT_TIMEOUT) {
|
|
Packit Service |
963350 |
res = 0;
|
|
Packit Service |
963350 |
} else if (wait_ret == WSA_WAIT_FAILED) {
|
|
Packit Service |
963350 |
res = -1;
|
|
Packit Service |
963350 |
errno = gst_poll_winsock_error_to_errno (WSAGetLastError ());
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
/* the first entry is the wakeup event */
|
|
Packit Service |
963350 |
if (wait_ret - WSA_WAIT_EVENT_0 >= 1) {
|
|
Packit Service |
963350 |
res = gst_poll_collect_winsock_events (set);
|
|
Packit Service |
963350 |
} else {
|
|
Packit Service |
963350 |
res = 1; /* wakeup event */
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
#else
|
|
Packit Service |
963350 |
g_assert_not_reached ();
|
|
Packit Service |
963350 |
errno = ENOSYS;
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
break;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (!is_timer) {
|
|
Packit Service |
963350 |
/* Applications needs to clear the control socket themselves for timer
|
|
Packit Service |
963350 |
* polls.
|
|
Packit Service |
963350 |
* For other polls, we need to clear the control socket. If there was only
|
|
Packit Service |
963350 |
* one socket with activity and it was the control socket, we need to
|
|
Packit Service |
963350 |
* restart */
|
|
Packit Service |
963350 |
if (release_all_wakeup (set) > 0 && res == 1)
|
|
Packit Service |
963350 |
restarting = TRUE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* we got woken up and we are flushing, we need to stop */
|
|
Packit Service |
963350 |
if (G_UNLIKELY (IS_FLUSHING (set)))
|
|
Packit Service |
963350 |
goto flushing;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
} while (G_UNLIKELY (restarting));
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
DEC_WAITING (set);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return res;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* ERRORS */
|
|
Packit Service |
963350 |
already_waiting:
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
GST_LOG ("%p: we are already waiting", set);
|
|
Packit Service |
963350 |
DEC_WAITING (set);
|
|
Packit Service |
963350 |
errno = EPERM;
|
|
Packit Service |
963350 |
return -1;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
flushing:
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
GST_LOG ("%p: we are flushing", set);
|
|
Packit Service |
963350 |
DEC_WAITING (set);
|
|
Packit Service |
963350 |
errno = EBUSY;
|
|
Packit Service |
963350 |
return -1;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
#ifdef G_OS_WIN32
|
|
Packit Service |
963350 |
winsock_error:
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
GST_LOG ("%p: winsock error", set);
|
|
Packit Service |
963350 |
g_mutex_unlock (&set->lock);
|
|
Packit Service |
963350 |
DEC_WAITING (set);
|
|
Packit Service |
963350 |
return -1;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
#endif
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_set_controllable:
|
|
Packit Service |
963350 |
* @set: a #GstPoll.
|
|
Packit Service |
963350 |
* @controllable: new controllable state.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* When @controllable is %TRUE, this function ensures that future calls to
|
|
Packit Service |
963350 |
* gst_poll_wait() will be affected by gst_poll_restart() and
|
|
Packit Service |
963350 |
* gst_poll_set_flushing().
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* This function only works for non-timer #GstPoll objects created with
|
|
Packit Service |
963350 |
* gst_poll_new().
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Returns: %TRUE if the controllability of @set could be updated.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
gboolean
|
|
Packit Service |
963350 |
gst_poll_set_controllable (GstPoll * set, gboolean controllable)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
g_return_val_if_fail (set != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (!set->timer, FALSE);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
GST_LOG ("%p: controllable : %d", set, controllable);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
set->controllable = controllable;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return TRUE;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_restart:
|
|
Packit Service |
963350 |
* @set: a #GstPoll.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Restart any gst_poll_wait() that is in progress. This function is typically
|
|
Packit Service |
963350 |
* used after adding or removing descriptors to @set.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* If @set is not controllable, then this call will have no effect.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* This function only works for non-timer #GstPoll objects created with
|
|
Packit Service |
963350 |
* gst_poll_new().
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
void
|
|
Packit Service |
963350 |
gst_poll_restart (GstPoll * set)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
g_return_if_fail (set != NULL);
|
|
Packit Service |
963350 |
g_return_if_fail (!set->timer);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (set->controllable && GET_WAITING (set) > 0) {
|
|
Packit Service |
963350 |
/* we are controllable and waiting, wake up the waiter. The socket will be
|
|
Packit Service |
963350 |
* cleared by the _wait() thread and the poll will be restarted */
|
|
Packit Service |
963350 |
raise_wakeup (set);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_set_flushing:
|
|
Packit Service |
963350 |
* @set: a #GstPoll.
|
|
Packit Service |
963350 |
* @flushing: new flushing state.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* When @flushing is %TRUE, this function ensures that current and future calls
|
|
Packit Service |
963350 |
* to gst_poll_wait() will return -1, with errno set to EBUSY.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Unsetting the flushing state will restore normal operation of @set.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* This function only works for non-timer #GstPoll objects created with
|
|
Packit Service |
963350 |
* gst_poll_new().
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
void
|
|
Packit Service |
963350 |
gst_poll_set_flushing (GstPoll * set, gboolean flushing)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
g_return_if_fail (set != NULL);
|
|
Packit Service |
963350 |
g_return_if_fail (!set->timer);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
GST_LOG ("%p: flushing: %d", set, flushing);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/* update the new state first */
|
|
Packit Service |
963350 |
SET_FLUSHING (set, flushing);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
if (flushing && set->controllable && GET_WAITING (set) > 0) {
|
|
Packit Service |
963350 |
/* we are flushing, controllable and waiting, wake up the waiter. When we
|
|
Packit Service |
963350 |
* stop the flushing operation we don't clear the wakeup fd here, this will
|
|
Packit Service |
963350 |
* happen in the _wait() thread. */
|
|
Packit Service |
963350 |
raise_wakeup (set);
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_write_control:
|
|
Packit Service |
963350 |
* @set: a #GstPoll.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Write a byte to the control socket of the controllable @set.
|
|
Packit Service |
963350 |
* This function is mostly useful for timer #GstPoll objects created with
|
|
Packit Service |
963350 |
* gst_poll_new_timer().
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* It will make any current and future gst_poll_wait() function return with
|
|
Packit Service |
963350 |
* 1, meaning the control socket is set. After an equal amount of calls to
|
|
Packit Service |
963350 |
* gst_poll_read_control() have been performed, calls to gst_poll_wait() will
|
|
Packit Service |
963350 |
* block again until their timeout expired.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* This function only works for timer #GstPoll objects created with
|
|
Packit Service |
963350 |
* gst_poll_new_timer().
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Returns: %TRUE on success. %FALSE when when the byte could not be written.
|
|
Packit Service |
963350 |
* errno contains the detailed error code but will never be EAGAIN, EINTR or
|
|
Packit Service |
963350 |
* EWOULDBLOCK. %FALSE always signals a critical error.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
gboolean
|
|
Packit Service |
963350 |
gst_poll_write_control (GstPoll * set)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gboolean res;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_return_val_if_fail (set != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (set->timer, FALSE);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
res = raise_wakeup (set);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return res;
|
|
Packit Service |
963350 |
}
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
/**
|
|
Packit Service |
963350 |
* gst_poll_read_control:
|
|
Packit Service |
963350 |
* @set: a #GstPoll.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Read a byte from the control socket of the controllable @set.
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* This function only works for timer #GstPoll objects created with
|
|
Packit Service |
963350 |
* gst_poll_new_timer().
|
|
Packit Service |
963350 |
*
|
|
Packit Service |
963350 |
* Returns: %TRUE on success. %FALSE when when there was no byte to read or
|
|
Packit Service |
963350 |
* reading the byte failed. If there was no byte to read, and only then, errno
|
|
Packit Service |
963350 |
* will contain EWOULDBLOCK or EAGAIN. For all other values of errno this always signals a
|
|
Packit Service |
963350 |
* critical error.
|
|
Packit Service |
963350 |
*/
|
|
Packit Service |
963350 |
gboolean
|
|
Packit Service |
963350 |
gst_poll_read_control (GstPoll * set)
|
|
Packit Service |
963350 |
{
|
|
Packit Service |
963350 |
gboolean res;
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
g_return_val_if_fail (set != NULL, FALSE);
|
|
Packit Service |
963350 |
g_return_val_if_fail (set->timer, FALSE);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
res = release_wakeup (set);
|
|
Packit Service |
963350 |
|
|
Packit Service |
963350 |
return res;
|
|
Packit Service |
963350 |
}
|