/* GStreamer
 * Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
 * Copyright (C) 2004 Wim Taymans <wim.taymans@gmail.com>
 * Copyright (C) 2007 Peter Kjellerstedt <pkj@axis.com>
 * Copyright (C) 2008 Ole André Vadla Ravnås <ole.andre.ravnas@tandberg.com>
 *
 * gstpoll.c: File descriptor set
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * 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., 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 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
 * gst_poll_new(), the set can be used to wait for file descriptors to be
 * readable and/or writable. It is possible to make this wait be controlled
 * by specifying %TRUE for the @controllable flag when creating the set (or
 * later calling gst_poll_set_controllable()).
 *
 * 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().
 *
 * 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
 * in time. The wait can be controlled by calling gst_poll_restart() and
 * gst_poll_set_flushing().
 *
 * Once the file descriptor set has been waited for, one can use
 * gst_poll_fd_has_closed() to see if the file descriptor has been closed,
 * gst_poll_fd_has_error() to see if it has generated an error,
 * gst_poll_fd_can_read() to see if it is possible to read from the file
 * descriptor, and gst_poll_fd_can_write() to see if it is possible to
 * write to it.
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "gst_private.h"
#include "glib-compat-private.h"

#include <sys/types.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include <errno.h>
#include <fcntl.h>

#include <glib.h>

#ifdef G_OS_WIN32
#include <winsock2.h>
#else
#define _GNU_SOURCE 1
#ifdef HAVE_SYS_POLL_H
#include <sys/poll.h>
#endif
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#include <sys/time.h>
#include <sys/socket.h>
#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 <string.h>

/* The poll() emulation on OS/X doesn't handle fds=NULL, nfds=0,
 * so we prefer our own poll emulation.
 */
#if defined(BROKEN_POLL)
#undef HAVE_POLL
#endif

#include "gstpoll.h"

#define GST_CAT_DEFAULT GST_CAT_POLL

#ifdef G_OS_WIN32
typedef struct _WinsockFd WinsockFd;

struct _WinsockFd
{
  gint fd;
  glong event_mask;
  WSANETWORKEVENTS events;
  glong ignored_event_mask;
};
#endif

typedef enum
{
  GST_POLL_MODE_AUTO,
  GST_POLL_MODE_SELECT,
  GST_POLL_MODE_PSELECT,
  GST_POLL_MODE_POLL,
  GST_POLL_MODE_PPOLL,
  GST_POLL_MODE_WINDOWS
} GstPollMode;

struct _GstPoll
{
  GstPollMode mode;

  GMutex lock;
  /* array of fds, always written to and read from with lock */
  GArray *fds;
  /* array of active fds, only written to from the waiting thread with the
   * lock and read from with the lock or without the lock from the waiting
   * thread */
  GArray *active_fds;

#ifndef G_OS_WIN32
  GstPollFD control_read_fd;
  GstPollFD control_write_fd;
#else
  GArray *active_fds_ignored;
  GArray *events;
  GArray *active_events;

  HANDLE wakeup_event;
#endif

  gboolean controllable;
  volatile gint waiting;
  volatile gint control_pending;
  volatile gint flushing;
  gboolean timer;
  volatile gint rebuild;
};

static gboolean gst_poll_fd_ctl_read_unlocked (GstPoll * set, GstPollFD * fd,
    gboolean active);
static gboolean gst_poll_add_fd_unlocked (GstPoll * set, GstPollFD * fd);

#define IS_FLUSHING(s)      (g_atomic_int_get(&(s)->flushing))
#define SET_FLUSHING(s,val) (g_atomic_int_set(&(s)->flushing, (val)))

#define INC_WAITING(s)      (g_atomic_int_add(&(s)->waiting, 1))
#define DEC_WAITING(s)      (g_atomic_int_add(&(s)->waiting, -1))
#define GET_WAITING(s)      (g_atomic_int_get(&(s)->waiting))

#define TEST_REBUILD(s)     (g_atomic_int_compare_and_exchange(&(s)->rebuild, 1, 0))
#define MARK_REBUILD(s)     (g_atomic_int_set(&(s)->rebuild, 1))

#ifndef G_OS_WIN32

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

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] = "<unknown>";
    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] = "<unknown>";
    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] = "<unknown>";
    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
 * we can send special commands to control it */
static inline gboolean
raise_wakeup (GstPoll * set)
{
  gboolean result = TRUE;

  /* 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);
  }

  if (result) {
    set->control_pending++;
  }

  g_mutex_unlock (&set->lock);

  return result;
}

static inline gboolean
release_wakeup (GstPoll * set)
{
  gboolean result = FALSE;

  /* makes testing/modifying control_pending and RELEASE_EVENT() atomic. */
  g_mutex_lock (&set->lock);

  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;
}

static inline gint
release_all_wakeup (GstPoll * set)
{
  gint old;

  /* makes testing control_pending and RELEASE_EVENT() atomic. */
  g_mutex_lock (&set->lock);

  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;
}

static gint
find_index (GArray * array, GstPollFD * fd)
{
#ifndef G_OS_WIN32
  struct pollfd *ifd;
#else
  WinsockFd *ifd;
#endif
  guint i;

  /* start by assuming the index found in the fd is still valid */
  if (fd->idx >= 0 && fd->idx < array->len) {
#ifndef G_OS_WIN32
    ifd = &g_array_index (array, struct pollfd, fd->idx);
#else
    ifd = &g_array_index (array, WinsockFd, fd->idx);
#endif

    if (ifd->fd == fd->fd) {
      return fd->idx;
    }
  }

  /* the pollfd array has changed and we need to lookup the fd again */
  for (i = 0; i < array->len; i++) {
#ifndef G_OS_WIN32
    ifd = &g_array_index (array, struct pollfd, i);
#else
    ifd = &g_array_index (array, WinsockFd, i);
#endif

    if (ifd->fd == fd->fd) {
      fd->idx = (gint) i;
      return fd->idx;
    }
  }

  fd->idx = -1;
  return fd->idx;
}

#if !defined(HAVE_PPOLL) && defined(HAVE_POLL)
/* check if all file descriptors will fit in an fd_set */
static gboolean
selectable_fds (GstPoll * set)
{
  guint i;

  g_mutex_lock (&set->lock);
  for (i = 0; i < set->fds->len; i++) {
    struct pollfd *pfd = &g_array_index (set->fds, struct pollfd, i);

    if (pfd->fd >= FD_SETSIZE)
      goto too_many;
  }
  g_mutex_unlock (&set->lock);

  return TRUE;

too_many:
  {
    g_mutex_unlock (&set->lock);
    return FALSE;
  }
}

/* check if the timeout will convert to a timeout value used for poll()
 * without a loss of precision
 */
static gboolean
pollable_timeout (GstClockTime timeout)
{
  if (timeout == GST_CLOCK_TIME_NONE)
    return TRUE;

  /* not a nice multiple of milliseconds */
  if (timeout % 1000000)
    return FALSE;

  return TRUE;
}
#endif

static GstPollMode
choose_mode (GstPoll * set, GstClockTime timeout)
{
  GstPollMode mode;

  if (set->mode == GST_POLL_MODE_AUTO) {
#ifdef HAVE_PPOLL
    mode = GST_POLL_MODE_PPOLL;
#elif defined(HAVE_POLL)
    if (!selectable_fds (set) || pollable_timeout (timeout)) {
      mode = GST_POLL_MODE_POLL;
    } else {
#ifdef HAVE_PSELECT
      mode = GST_POLL_MODE_PSELECT;
#else
      mode = GST_POLL_MODE_SELECT;
#endif
    }
#elif defined(HAVE_PSELECT)
    mode = GST_POLL_MODE_PSELECT;
#else
    mode = GST_POLL_MODE_SELECT;
#endif
  } else {
    mode = set->mode;
  }
  return mode;
}

#ifndef G_OS_WIN32
static gint
pollfd_to_fd_set (GstPoll * set, fd_set * readfds, fd_set * writefds,
    fd_set * errorfds)
{
  gint max_fd = -1;
  guint i;

  FD_ZERO (readfds);
  FD_ZERO (writefds);
  FD_ZERO (errorfds);

  g_mutex_lock (&set->lock);

  for (i = 0; i < set->active_fds->len; i++) {
    struct pollfd *pfd = &g_array_index (set->fds, struct pollfd, i);

    if (pfd->fd < FD_SETSIZE) {
      if (pfd->events & POLLIN)
        FD_SET (pfd->fd, readfds);
      if (pfd->events & POLLOUT)
        FD_SET (pfd->fd, writefds);
      if (pfd->events)
        FD_SET (pfd->fd, errorfds);
      if (pfd->fd > max_fd && (pfd->events & (POLLIN | POLLOUT)))
        max_fd = pfd->fd;
    }
  }

  g_mutex_unlock (&set->lock);

  return max_fd;
}

static void
fd_set_to_pollfd (GstPoll * set, fd_set * readfds, fd_set * writefds,
    fd_set * errorfds)
{
  guint i;

  g_mutex_lock (&set->lock);

  for (i = 0; i < set->active_fds->len; i++) {
    struct pollfd *pfd = &g_array_index (set->active_fds, struct pollfd, i);

    if (pfd->fd < FD_SETSIZE) {
      pfd->revents = 0;
      if (FD_ISSET (pfd->fd, readfds))
        pfd->revents |= POLLIN;
      if (FD_ISSET (pfd->fd, writefds))
        pfd->revents |= POLLOUT;
      if (FD_ISSET (pfd->fd, errorfds))
        pfd->revents |= POLLERR;
    }
  }

  g_mutex_unlock (&set->lock);
}
#else /* G_OS_WIN32 */
/*
 * Translate errors thrown by the Winsock API used by GstPoll:
 *   WSAEventSelect, WSAWaitForMultipleEvents and WSAEnumNetworkEvents
 */
static gint
gst_poll_winsock_error_to_errno (DWORD last_error)
{
  switch (last_error) {
    case WSA_INVALID_HANDLE:
    case WSAEINVAL:
    case WSAENOTSOCK:
      return EBADF;

    case WSA_NOT_ENOUGH_MEMORY:
      return ENOMEM;

      /*
       * Anything else, including:
       *   WSA_INVALID_PARAMETER, WSAEFAULT, WSAEINPROGRESS, WSAENETDOWN,
       *   WSANOTINITIALISED
       */
    default:
      return EINVAL;
  }
}

static void
gst_poll_free_winsock_event (GstPoll * set, gint idx)
{
  WinsockFd *wfd = &g_array_index (set->fds, WinsockFd, idx);
  HANDLE event = g_array_index (set->events, HANDLE, idx);

  WSAEventSelect (wfd->fd, event, 0);
  CloseHandle (event);
}

static void
gst_poll_update_winsock_event_mask (GstPoll * set, gint idx, glong flags,
    gboolean active)
{
  WinsockFd *wfd;

  wfd = &g_array_index (set->fds, WinsockFd, idx);

  if (active)
    wfd->event_mask |= flags;
  else
    wfd->event_mask &= ~flags;

  /* reset ignored state if the new mask doesn't overlap at all */
  if ((wfd->ignored_event_mask & wfd->event_mask) == 0)
    wfd->ignored_event_mask = 0;
}

static gboolean
gst_poll_prepare_winsock_active_sets (GstPoll * set)
{
  guint i;

  g_array_set_size (set->active_fds, 0);
  g_array_set_size (set->active_fds_ignored, 0);
  g_array_set_size (set->active_events, 0);
  g_array_append_val (set->active_events, set->wakeup_event);

  for (i = 0; i < set->fds->len; i++) {
    WinsockFd *wfd = &g_array_index (set->fds, WinsockFd, i);
    HANDLE event = g_array_index (set->events, HANDLE, i);

    if (wfd->ignored_event_mask == 0) {
      gint ret;

      g_array_append_val (set->active_fds, *wfd);
      g_array_append_val (set->active_events, event);

      ret = WSAEventSelect (wfd->fd, event, wfd->event_mask);
      if (G_UNLIKELY (ret != 0)) {
        errno = gst_poll_winsock_error_to_errno (WSAGetLastError ());
        return FALSE;
      }
    } else {
      g_array_append_val (set->active_fds_ignored, wfd);
    }
  }

  return TRUE;
}

static gint
gst_poll_collect_winsock_events (GstPoll * set)
{
  gint res, i;

  /*
   * We need to check which events are signaled, and call
   * WSAEnumNetworkEvents for those that are, which resets
   * the event and clears the internal network event records.
   */
  res = 0;
  for (i = 0; i < set->active_fds->len; i++) {
    WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, i);
    HANDLE event = g_array_index (set->active_events, HANDLE, i + 1);
    DWORD wait_ret;

    wait_ret = WaitForSingleObject (event, 0);
    if (wait_ret == WAIT_OBJECT_0) {
      gint enum_ret = WSAEnumNetworkEvents (wfd->fd, event, &wfd->events);

      if (G_UNLIKELY (enum_ret != 0)) {
        res = -1;
        errno = gst_poll_winsock_error_to_errno (WSAGetLastError ());
        break;
      }

      res++;
    } else {
      /* clear any previously stored result */
      memset (&wfd->events, 0, sizeof (wfd->events));
    }
  }

  /* If all went well we also need to reset the ignored fds. */
  if (res >= 0) {
    res += set->active_fds_ignored->len;

    for (i = 0; i < set->active_fds_ignored->len; i++) {
      WinsockFd *wfd = g_array_index (set->active_fds_ignored, WinsockFd *, i);

      wfd->ignored_event_mask = 0;
    }

    g_array_set_size (set->active_fds_ignored, 0);
  }

  return res;
}
#endif

/**
 * gst_poll_new: (skip)
 * @controllable: whether it should be possible to control a wait.
 *
 * Create a new file descriptor set. If @controllable, it
 * is possible to restart or flush a call to gst_poll_wait() with
 * gst_poll_restart() and gst_poll_set_flushing() respectively.
 *
 * Free-function: gst_poll_free
 *
 * 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;

  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;
  nset->fds = g_array_new (FALSE, FALSE, sizeof (struct pollfd));
  nset->active_fds = g_array_new (FALSE, FALSE, sizeof (struct pollfd));
  nset->control_read_fd.fd = -1;
  nset->control_write_fd.fd = -1;
  {
    gint control_sock[2];

    if (socketpair (PF_UNIX, SOCK_STREAM, 0, control_sock) < 0)
      goto no_socket_pair;

    nset->control_read_fd.fd = control_sock[0];
    nset->control_write_fd.fd = control_sock[1];

    gst_poll_add_fd_unlocked (nset, &nset->control_read_fd);
    gst_poll_fd_ctl_read_unlocked (nset, &nset->control_read_fd, TRUE);
  }
#else
  nset->mode = GST_POLL_MODE_WINDOWS;
  nset->fds = g_array_new (FALSE, FALSE, sizeof (WinsockFd));
  nset->active_fds = g_array_new (FALSE, FALSE, sizeof (WinsockFd));
  nset->active_fds_ignored = g_array_new (FALSE, FALSE, sizeof (WinsockFd *));
  nset->events = g_array_new (FALSE, FALSE, sizeof (HANDLE));
  nset->active_events = g_array_new (FALSE, FALSE, sizeof (HANDLE));

  nset->wakeup_event = CreateEvent (NULL, TRUE, FALSE, NULL);
#endif

  /* ensure (re)build, though already sneakily set in non-windows case */
  MARK_REBUILD (nset);

  nset->controllable = controllable;
  nset->control_pending = 0;

  return nset;

  /* ERRORS */
#ifndef G_OS_WIN32
no_socket_pair:
  {
    GST_WARNING ("%p: can't create socket pair !", nset);
    gst_poll_free (nset);
    return NULL;
  }
#endif
}

/**
 * gst_poll_new_timer: (skip)
 *
 * Create a new poll object that can be used for scheduling cancellable
 * timeouts.
 *
 * A timeout is performed with gst_poll_wait(). Multiple timeouts can be
 * performed from different threads.
 *
 * Free-function: gst_poll_free
 *
 * 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)
{
  GstPoll *poll;

  /* make a new controllable poll set */
  if (!(poll = gst_poll_new (TRUE)))
    goto done;

  /* we are a timer */
  poll->timer = TRUE;

done:
  return poll;
}

/**
 * gst_poll_free:
 * @set: (transfer full): a file descriptor set.
 *
 * Free a file descriptor set.
 */
void
gst_poll_free (GstPoll * set)
{
  g_return_if_fail (set != NULL);

  GST_DEBUG ("%p: freeing", set);

#ifndef G_OS_WIN32
  if (set->control_write_fd.fd >= 0)
    close (set->control_write_fd.fd);
  if (set->control_read_fd.fd >= 0)
    close (set->control_read_fd.fd);
#else
  CloseHandle (set->wakeup_event);

  {
    guint i;

    for (i = 0; i < set->events->len; i++)
      gst_poll_free_winsock_event (set, i);
  }

  g_array_free (set->active_events, TRUE);
  g_array_free (set->events, TRUE);
  g_array_free (set->active_fds_ignored, TRUE);
#endif

  g_array_free (set->active_fds, TRUE);
  g_array_free (set->fds, TRUE);
  g_mutex_clear (&set->lock);
  g_slice_free (GstPoll, set);
}

/**
 * gst_poll_get_read_gpollfd:
 * @set: a #GstPoll
 * @fd: a #GPollFD
 *
 * Get a GPollFD for the reading part of the control socket. This is useful when
 * integrating with a GSource and GMainLoop.
 */
void
gst_poll_get_read_gpollfd (GstPoll * set, GPollFD * fd)
{
  g_return_if_fail (set != NULL);
  g_return_if_fail (fd != NULL);

#ifndef G_OS_WIN32
  fd->fd = set->control_read_fd.fd;
#else
#if GLIB_SIZEOF_VOID_P == 8
  fd->fd = (gint64) set->wakeup_event;
#else
  fd->fd = (gint) set->wakeup_event;
#endif
#endif
  fd->events = G_IO_IN | G_IO_HUP | G_IO_ERR;
  fd->revents = 0;
}

/**
 * gst_poll_fd_init:
 * @fd: a #GstPollFD
 *
 * Initializes @fd. Alternatively you can initialize it with
 * #GST_POLL_FD_INIT.
 */
void
gst_poll_fd_init (GstPollFD * fd)
{
  g_return_if_fail (fd != NULL);

  fd->fd = -1;
  fd->idx = -1;
}

static gboolean
gst_poll_add_fd_unlocked (GstPoll * set, GstPollFD * fd)
{
  gint idx;

  GST_DEBUG ("%p: fd (fd:%d, idx:%d)", set, fd->fd, fd->idx);

  idx = find_index (set->fds, fd);
  if (idx < 0) {
#ifndef G_OS_WIN32
    struct pollfd nfd;

    nfd.fd = fd->fd;
    nfd.events = POLLERR | POLLNVAL | POLLHUP;
    nfd.revents = 0;

    g_array_append_val (set->fds, nfd);

    fd->idx = set->fds->len - 1;
#else
    WinsockFd wfd;
    HANDLE event;

    wfd.fd = fd->fd;
    wfd.event_mask = FD_CLOSE;
    memset (&wfd.events, 0, sizeof (wfd.events));
    wfd.ignored_event_mask = 0;
    event = WSACreateEvent ();

    g_array_append_val (set->fds, wfd);
    g_array_append_val (set->events, event);

    fd->idx = set->fds->len - 1;
#endif
    MARK_REBUILD (set);
  } else {
    GST_WARNING ("%p: fd already added !", set);
  }

  return TRUE;
}

/**
 * gst_poll_add_fd:
 * @set: a file descriptor set.
 * @fd: a file descriptor.
 *
 * Add a file descriptor to the file descriptor set.
 *
 * Returns: %TRUE if the file descriptor was successfully added to the set.
 */
gboolean
gst_poll_add_fd (GstPoll * set, GstPollFD * fd)
{
  gboolean ret;

  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 (&set->lock);

  ret = gst_poll_add_fd_unlocked (set, fd);

  g_mutex_unlock (&set->lock);

  return ret;
}

/**
 * gst_poll_remove_fd:
 * @set: a file descriptor set.
 * @fd: a file descriptor.
 *
 * Remove a file descriptor from the file descriptor set.
 *
 * Returns: %TRUE if the file descriptor was successfully removed from the set.
 */
gboolean
gst_poll_remove_fd (GstPoll * set, GstPollFD * fd)
{
  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)", set, fd->fd, fd->idx);

  g_mutex_lock (&set->lock);

  /* get the index, -1 is an fd that is not added */
  idx = find_index (set->fds, fd);
  if (idx >= 0) {
#ifdef G_OS_WIN32
    gst_poll_free_winsock_event (set, idx);
    g_array_remove_index_fast (set->events, idx);
#endif

    /* remove the fd at index, we use _remove_index_fast, which copies the last
     * element of the array to the freed index */
    g_array_remove_index_fast (set->fds, idx);

    /* mark fd as removed by setting the index to -1 */
    fd->idx = -1;
    MARK_REBUILD (set);
  } else {
    GST_WARNING ("%p: couldn't find fd !", set);
  }

  g_mutex_unlock (&set->lock);

  return idx >= 0;
}

/**
 * gst_poll_fd_ctl_write:
 * @set: a file descriptor set.
 * @fd: a file descriptor.
 * @active: a new status.
 *
 * Control whether the descriptor @fd in @set will be monitored for
 * writability.
 *
 * Returns: %TRUE if the descriptor was successfully updated.
 */
gboolean
gst_poll_fd_ctl_write (GstPoll * set, GstPollFD * fd, gboolean active)
{
  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) {
#ifndef G_OS_WIN32
    struct pollfd *pfd = &g_array_index (set->fds, struct pollfd, idx);

    if (active)
      pfd->events |= POLLOUT;
    else
      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);
#endif
    MARK_REBUILD (set);
  } else {
    GST_WARNING ("%p: couldn't find fd !", set);
  }

  g_mutex_unlock (&set->lock);

  return idx >= 0;
}

static gboolean
gst_poll_fd_ctl_read_unlocked (GstPoll * set, GstPollFD * fd, gboolean active)
{
  gint idx;

  GST_DEBUG ("%p: fd (fd:%d, idx:%d), active : %d", set,
      fd->fd, fd->idx, active);

  idx = find_index (set->fds, fd);

  if (idx >= 0) {
#ifndef G_OS_WIN32
    struct pollfd *pfd = &g_array_index (set->fds, struct pollfd, idx);

    if (active)
      pfd->events |= (POLLIN | POLLPRI);
    else
      pfd->events &= ~(POLLIN | POLLPRI);
#else
    gst_poll_update_winsock_event_mask (set, idx, FD_READ | FD_ACCEPT, active);
#endif
    MARK_REBUILD (set);
  } else {
    GST_WARNING ("%p: couldn't find fd !", set);
  }

  return idx >= 0;
}

/**
 * gst_poll_fd_ctl_read:
 * @set: a file descriptor set.
 * @fd: a file descriptor.
 * @active: a new status.
 *
 * Control whether the descriptor @fd in @set will be monitored for
 * readability.
 *
 * Returns: %TRUE if the descriptor was successfully updated.
 */
gboolean
gst_poll_fd_ctl_read (GstPoll * set, GstPollFD * fd, gboolean active)
{
  gboolean ret;

  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 (&set->lock);

  ret = gst_poll_fd_ctl_read_unlocked (set, fd, active);

  g_mutex_unlock (&set->lock);

  return ret;
}

/**
 * gst_poll_fd_ignored:
 * @set: a file descriptor set.
 * @fd: a file descriptor.
 *
 * Mark @fd as ignored so that the next call to gst_poll_wait() will yield
 * the same result for @fd as last time. This function must be called if no
 * operation (read/write/recv/send/etc.) will be performed on @fd before
 * the next call to gst_poll_wait().
 *
 * 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.
 */
void
gst_poll_fd_ignored (GstPoll * set, GstPollFD * fd)
{
#ifdef G_OS_WIN32
  gint idx;

  g_return_if_fail (set != NULL);
  g_return_if_fail (fd != NULL);
  g_return_if_fail (fd->fd >= 0);

  g_mutex_lock (&set->lock);

  idx = find_index (set->fds, fd);
  if (idx >= 0) {
    WinsockFd *wfd = &g_array_index (set->fds, WinsockFd, idx);

    wfd->ignored_event_mask = wfd->event_mask & (FD_READ | FD_WRITE);
    MARK_REBUILD (set);
  }

  g_mutex_unlock (&set->lock);
#endif
}

/**
 * gst_poll_fd_has_closed:
 * @set: a file descriptor set.
 * @fd: a file descriptor.
 *
 * Check if @fd in @set has closed the connection.
 *
 * Returns: %TRUE if the connection was closed.
 */
gboolean
gst_poll_fd_has_closed (const GstPoll * set, GstPollFD * fd)
{
  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) {
#ifndef G_OS_WIN32
    struct pollfd *pfd = &g_array_index (set->active_fds, struct pollfd, idx);

    res = (pfd->revents & POLLHUP) != 0;
#else
    WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, idx);

    res = (wfd->events.lNetworkEvents & FD_CLOSE) != 0;
#endif
  } 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_error:
 * @set: a file descriptor set.
 * @fd: a file descriptor.
 *
 * Check if @fd in @set has an error.
 *
 * Returns: %TRUE if the descriptor has an error.
 */
gboolean
gst_poll_fd_has_error (const GstPoll * set, GstPollFD * fd)
{
  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) {
#ifndef G_OS_WIN32
    struct pollfd *pfd = &g_array_index (set->active_fds, struct pollfd, idx);

    res = (pfd->revents & (POLLERR | POLLNVAL)) != 0;
#else
    WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, idx);

    res = (wfd->events.iErrorCode[FD_CLOSE_BIT] != 0) ||
        (wfd->events.iErrorCode[FD_READ_BIT] != 0) ||
        (wfd->events.iErrorCode[FD_WRITE_BIT] != 0) ||
        (wfd->events.iErrorCode[FD_ACCEPT_BIT] != 0) ||
        (wfd->events.iErrorCode[FD_CONNECT_BIT] != 0);
#endif
  } 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;
}

static gboolean
gst_poll_fd_can_read_unlocked (const GstPoll * set, GstPollFD * fd)
{
  gboolean res = FALSE;
  gint 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;
#else
    WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, idx);

    res = (wfd->events.lNetworkEvents & (FD_READ | FD_ACCEPT)) != 0;
#endif
  } 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;
}

/**
 * gst_poll_fd_can_read:
 * @set: a file descriptor set.
 * @fd: a file descriptor.
 *
 * Check if @fd in @set has data to be read.
 *
 * Returns: %TRUE if the descriptor has data to be read.
 */
gboolean
gst_poll_fd_can_read (const GstPoll * set, GstPollFD * fd)
{
  gboolean res = FALSE;

  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);

  res = gst_poll_fd_can_read_unlocked (set, fd);

  g_mutex_unlock (&((GstPoll *) set)->lock);

  return res;
}

/**
 * gst_poll_fd_can_write:
 * @set: a file descriptor set.
 * @fd: a file descriptor.
 *
 * Check if @fd in @set can be used for writing.
 *
 * Returns: %TRUE if the descriptor can be used for writing.
 */
gboolean
gst_poll_fd_can_write (const GstPoll * set, GstPollFD * fd)
{
  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) {
#ifndef G_OS_WIN32
    struct pollfd *pfd = &g_array_index (set->active_fds, struct pollfd, idx);

    res = (pfd->revents & POLLOUT) != 0;
#else
    WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, idx);

    res = (wfd->events.lNetworkEvents & FD_WRITE) != 0;
#endif
  } 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_wait:
 * @set: a #GstPoll.
 * @timeout: a timeout in nanoseconds.
 *
 * Wait for activity on the file descriptors in @set. This function waits up to
 * the specified @timeout.  A timeout of #GST_CLOCK_TIME_NONE waits forever.
 *
 * For #GstPoll objects created with gst_poll_new(), this function can only be
 * called from a single thread at a time.  If called from multiple threads,
 * -1 will be returned with errno set to EPERM.
 *
 * This is not true for timer #GstPoll objects created with
 * gst_poll_new_timer(), where it is allowed to have multiple threads waiting
 * simultaneously.
 *
 * 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.
 */
gint
gst_poll_wait (GstPoll * set, GstClockTime timeout)
{
  gboolean restarting;
  gboolean is_timer;
  int res;
  gint old_waiting;

  g_return_val_if_fail (set != NULL, -1);

  GST_DEBUG ("%p: timeout :%" GST_TIME_FORMAT, set, GST_TIME_ARGS (timeout));

  is_timer = set->timer;

  /* add one more waiter */
  old_waiting = INC_WAITING (set);

  /* we cannot wait from multiple threads unless we are a timer */
  if (G_UNLIKELY (old_waiting > 0 && !is_timer))
    goto already_waiting;

  /* flushing, exit immediately */
  if (G_UNLIKELY (IS_FLUSHING (set)))
    goto flushing;

  do {
    GstPollMode mode;

    res = -1;
    restarting = FALSE;

    mode = choose_mode (set, timeout);

    if (TEST_REBUILD (set)) {
      g_mutex_lock (&set->lock);
#ifndef G_OS_WIN32
      g_array_set_size (set->active_fds, set->fds->len);
      memcpy (set->active_fds->data, set->fds->data,
          set->fds->len * sizeof (struct pollfd));
#else
      if (!gst_poll_prepare_winsock_active_sets (set))
        goto winsock_error;
#endif
      g_mutex_unlock (&set->lock);
    }

    switch (mode) {
      case GST_POLL_MODE_AUTO:
        g_assert_not_reached ();
        break;
      case GST_POLL_MODE_PPOLL:
      {
#ifdef HAVE_PPOLL
        struct timespec ts;
        struct timespec *tsptr;

        if (timeout != GST_CLOCK_TIME_NONE) {
          GST_TIME_TO_TIMESPEC (timeout, ts);
          tsptr = &ts;
        } else {
          tsptr = NULL;
        }

        res =
            ppoll ((struct pollfd *) set->active_fds->data,
            set->active_fds->len, tsptr, NULL);
#else
        g_assert_not_reached ();
        errno = ENOSYS;
#endif
        break;
      }
      case GST_POLL_MODE_POLL:
      {
#ifdef HAVE_POLL
        gint t;

        if (timeout != GST_CLOCK_TIME_NONE) {
          t = GST_TIME_AS_MSECONDS (timeout);
        } else {
          t = -1;
        }

        res =
            poll ((struct pollfd *) set->active_fds->data,
            set->active_fds->len, t);
#else
        g_assert_not_reached ();
        errno = ENOSYS;
#endif
        break;
      }
      case GST_POLL_MODE_PSELECT:
#ifndef HAVE_PSELECT
      {
        g_assert_not_reached ();
        errno = ENOSYS;
        break;
      }
#endif
      case GST_POLL_MODE_SELECT:
      {
#ifndef G_OS_WIN32
        fd_set readfds;
        fd_set writefds;
        fd_set errorfds;
        gint max_fd;

        max_fd = pollfd_to_fd_set (set, &readfds, &writefds, &errorfds);

        if (mode == GST_POLL_MODE_SELECT) {
          struct timeval tv;
          struct timeval *tvptr;

          if (timeout != GST_CLOCK_TIME_NONE) {
            GST_TIME_TO_TIMEVAL (timeout, tv);
            tvptr = &tv;
          } else {
            tvptr = NULL;
          }

          GST_DEBUG ("%p: Calling select", set);
          res = select (max_fd + 1, &readfds, &writefds, &errorfds, tvptr);
          GST_DEBUG ("%p: After select, res:%d", set, res);
        } else {
#ifdef HAVE_PSELECT
          struct timespec ts;
          struct timespec *tsptr;

          if (timeout != GST_CLOCK_TIME_NONE) {
            GST_TIME_TO_TIMESPEC (timeout, ts);
            tsptr = &ts;
          } else {
            tsptr = NULL;
          }

          GST_DEBUG ("%p: Calling pselect", set);
          res =
              pselect (max_fd + 1, &readfds, &writefds, &errorfds, tsptr, NULL);
          GST_DEBUG ("%p: After pselect, res:%d", set, res);
#endif
        }

        if (res >= 0) {
          fd_set_to_pollfd (set, &readfds, &writefds, &errorfds);
        }
#else /* G_OS_WIN32 */
        g_assert_not_reached ();
        errno = ENOSYS;
#endif
        break;
      }
      case GST_POLL_MODE_WINDOWS:
      {
#ifdef G_OS_WIN32
        gint ignore_count = set->active_fds_ignored->len;
        DWORD t, wait_ret;

        if (G_LIKELY (ignore_count == 0)) {
          if (timeout != GST_CLOCK_TIME_NONE)
            t = GST_TIME_AS_MSECONDS (timeout);
          else
            t = INFINITE;
        } else {
          /* already one or more ignored fds, so we quickly sweep the others */
          t = 0;
        }

        if (set->active_events->len != 0) {
          wait_ret = WSAWaitForMultipleEvents (set->active_events->len,
              (HANDLE *) set->active_events->data, FALSE, t, FALSE);
        } else {
          wait_ret = WSA_WAIT_FAILED;
          WSASetLastError (WSA_INVALID_PARAMETER);
        }

        if (ignore_count == 0 && wait_ret == WSA_WAIT_TIMEOUT) {
          res = 0;
        } else if (wait_ret == WSA_WAIT_FAILED) {
          res = -1;
          errno = gst_poll_winsock_error_to_errno (WSAGetLastError ());
        } else {
          /* the first entry is the wakeup event */
          if (wait_ret - WSA_WAIT_EVENT_0 >= 1) {
            res = gst_poll_collect_winsock_events (set);
          } else {
            res = 1;            /* wakeup event */
          }
        }
#else
        g_assert_not_reached ();
        errno = ENOSYS;
#endif
        break;
      }
    }

    if (!is_timer) {
      /* Applications needs to clear the control socket themselves for timer
       * polls.
       * For other polls, we need to clear the control socket. If there was only
       * one socket with activity and it was the control socket, we need to
       * restart */
      if (release_all_wakeup (set) > 0 && res == 1)
        restarting = TRUE;
    }

    /* we got woken up and we are flushing, we need to stop */
    if (G_UNLIKELY (IS_FLUSHING (set)))
      goto flushing;

  } while (G_UNLIKELY (restarting));

  DEC_WAITING (set);

  return res;

  /* ERRORS */
already_waiting:
  {
    GST_LOG ("%p: we are already waiting", set);
    DEC_WAITING (set);
    errno = EPERM;
    return -1;
  }
flushing:
  {
    GST_LOG ("%p: we are flushing", set);
    DEC_WAITING (set);
    errno = EBUSY;
    return -1;
  }
#ifdef G_OS_WIN32
winsock_error:
  {
    GST_LOG ("%p: winsock error", set);
    g_mutex_unlock (&set->lock);
    DEC_WAITING (set);
    return -1;
  }
#endif
}

/**
 * gst_poll_set_controllable:
 * @set: a #GstPoll.
 * @controllable: new controllable state.
 *
 * When @controllable is %TRUE, this function ensures that future calls to
 * gst_poll_wait() will be affected by gst_poll_restart() and
 * gst_poll_set_flushing().
 *
 * This function only works for non-timer #GstPoll objects created with
 * gst_poll_new().
 *
 * 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);

  set->controllable = controllable;

  return TRUE;
}

/**
 * gst_poll_restart:
 * @set: a #GstPoll.
 *
 * Restart any gst_poll_wait() that is in progress. This function is typically
 * used after adding or removing descriptors to @set.
 *
 * If @set is not controllable, then this call will have no effect.
 *
 * 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
     * cleared by the _wait() thread and the poll will be restarted */
    raise_wakeup (set);
  }
}

/**
 * gst_poll_set_flushing:
 * @set: a #GstPoll.
 * @flushing: new flushing state.
 *
 * When @flushing is %TRUE, this function ensures that current and future calls
 * to gst_poll_wait() will return -1, with errno set to EBUSY.
 *
 * Unsetting the flushing state will restore normal operation of @set.
 *
 * 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);

  /* update the new state first */
  SET_FLUSHING (set, flushing);

  if (flushing && set->controllable && GET_WAITING (set) > 0) {
    /* we are flushing, controllable and waiting, wake up the waiter. When we
     * stop the flushing operation we don't clear the wakeup fd here, this will
     * happen in the _wait() thread. */
    raise_wakeup (set);
  }
}

/**
 * gst_poll_write_control:
 * @set: a #GstPoll.
 *
 * 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().
 *
 * 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.
 *
 * This function only works for timer #GstPoll objects created with
 * gst_poll_new_timer().
 *
 * 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)
{
  gboolean res;

  g_return_val_if_fail (set != NULL, FALSE);
  g_return_val_if_fail (set->timer, FALSE);

  res = raise_wakeup (set);

  return res;
}

/**
 * gst_poll_read_control:
 * @set: a #GstPoll.
 *
 * Read a byte from the control socket of the controllable @set.
 *
 * This function only works for timer #GstPoll objects created with
 * gst_poll_new_timer().
 *
 * 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)
{
  gboolean res;

  g_return_val_if_fail (set != NULL, FALSE);
  g_return_val_if_fail (set->timer, FALSE);

  res = release_wakeup (set);

  return res;
}
