gstreamer_core/gst/gstpoll.c
changeset 0 0e761a78d257
child 8 4a7fac7dd34a
equal deleted inserted replaced
-1:000000000000 0:0e761a78d257
       
     1 /* GStreamer
       
     2  * Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
       
     3  * Copyright (C) 2004 Wim Taymans <wim.taymans@gmail.com>
       
     4  * Copyright (C) 2007 Peter Kjellerstedt <pkj@axis.com>
       
     5  * Copyright (C) 2008 Ole André Vadla Ravnås <ole.andre.ravnas@tandberg.com>
       
     6  *
       
     7  * gstpoll.c: File descriptor set
       
     8  *
       
     9  * This library is free software; you can redistribute it and/or
       
    10  * modify it under the terms of the GNU Library General Public
       
    11  * License as published by the Free Software Foundation; either
       
    12  * version 2 of the License, or (at your option) any later version.
       
    13  *
       
    14  * This library is distributed in the hope that it will be useful,
       
    15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    17  * Library General Public License for more details.
       
    18  *
       
    19  * You should have received a copy of the GNU Library General Public
       
    20  * License along with this library; if not, write to the
       
    21  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
       
    22  * Boston, MA 02111-1307, USA.
       
    23  */
       
    24 /**
       
    25  * SECTION:gstpoll
       
    26  * @short_description: Keep track of file descriptors and make it possible
       
    27  *                     to wait on them in a cancelable way
       
    28  *
       
    29  * A #GstPoll keeps track of file descriptors much like fd_set (used with
       
    30  * select()) or a struct pollfd array (used with poll()). Once created with
       
    31  * gst_poll_new(), the set can be used to wait for file descriptors to be
       
    32  * readable and/or writeable. It is possible to make this wait be controlled
       
    33  * by specifying %TRUE for the @controllable flag when creating the set (or
       
    34  * later calling gst_poll_set_controllable()).
       
    35  *
       
    36  * New file descriptors are added to the set using gst_poll_add_fd(), and
       
    37  * removed using gst_poll_remove_fd(). Controlling which file descriptors
       
    38  * should be waited for to become readable and/
       
    39 #ifdef __SYMBIAN32__
       
    40 EXPORT_C
       
    41 #endif
       
    42 or writeable are done using
       
    43  * gst_poll_fd_ctl_read() and gst_poll_fd_ctl_write().
       
    44  *
       
    45  * Use gst_poll_wait() to wait for the file descriptors to actually become
       
    46  * readable and/or writeable, or to timeout if no file descriptor is available
       
    47  * in time. The wait can be controlled by calling gst_poll_restart() and
       
    48  * gst_poll_set_flushing().
       
    49  *
       
    50  * Once the file descriptor set has been waited for, one can use
       
    51  * gst_poll_fd_has_closed() to see if the file descriptor has been closed,
       
    52  * gst_poll_fd_has_error() to see if it has generated an error,
       
    53  * gst_poll_fd_can_read() to see if it is possible to read from the file
       
    54  * descriptor, and gst_poll_fd_can_write() to see if it is possible to
       
    55  * write to it.
       
    56  *
       
    57  */
       
    58 
       
    59 #ifdef HAVE_CONFIG_H
       
    60 #include "config.h"
       
    61 #endif
       
    62 
       
    63 #ifndef _MSC_VER
       
    64 #define _GNU_SOURCE 1
       
    65 #ifndef __SYMBIAN32__
       
    66 #include <sys/poll.h>
       
    67 #endif
       
    68 #include <sys/time.h>
       
    69 #endif
       
    70 
       
    71 #include <sys/types.h>
       
    72 
       
    73 #ifdef HAVE_UNISTD_H
       
    74 #include <unistd.h>
       
    75 #endif
       
    76 
       
    77 #include <errno.h>
       
    78 #include <fcntl.h>
       
    79 
       
    80 #include <glib.h>
       
    81 
       
    82 #ifdef G_OS_WIN32
       
    83 #include <winsock2.h>
       
    84 #define EINPROGRESS WSAEINPROGRESS
       
    85 #else
       
    86 #include <sys/socket.h>
       
    87 #endif
       
    88 
       
    89 /* OS/X needs this because of bad headers */
       
    90 #include <string.h>
       
    91 
       
    92 #include "gst_private.h"
       
    93 
       
    94 #include "gstpoll.h"
       
    95 
       
    96 #ifdef __SYMBIAN32__
       
    97 #include <glib_global.h>
       
    98 #include <sys/select.h>
       
    99 #include <garray.h>
       
   100 #include <glibconfig.h>
       
   101 #include <gthread.h>
       
   102 
       
   103 #define POLLIN  1
       
   104 #define POLLOUT 4
       
   105 #define POLLPRI 2
       
   106 #define POLLHUP 6
       
   107 #define POLLERR 8
       
   108 #define POLLNVAL 32
       
   109 
       
   110 #endif
       
   111 #ifndef G_OS_WIN32
       
   112 /* the poll/select call is also performed on a control socket, that way
       
   113  * we can send special commands to control it
       
   114  */
       
   115 #define SEND_COMMAND(set, command)                   \
       
   116 G_STMT_START {                                       \
       
   117   unsigned char c = command;                         \
       
   118   write (set->control_write_fd.fd, &c, 1);           \
       
   119 } G_STMT_END
       
   120 
       
   121 #define READ_COMMAND(set, command, res)              \
       
   122 G_STMT_START {                                       \
       
   123   res = read (set->control_read_fd.fd, &command, 1); \
       
   124 } G_STMT_END
       
   125 
       
   126 #define GST_POLL_CMD_WAKEUP  'W'        /* restart the poll/select call */
       
   127 
       
   128 #else /* G_OS_WIN32 */
       
   129 typedef struct _WinsockFd WinsockFd;
       
   130 
       
   131 struct _WinsockFd
       
   132 {
       
   133   gint fd;
       
   134   glong event_mask;
       
   135   WSANETWORKEVENTS events;
       
   136   glong ignored_event_mask;
       
   137 };
       
   138 #endif
       
   139 
       
   140 typedef enum
       
   141 {
       
   142   GST_POLL_MODE_AUTO,
       
   143   GST_POLL_MODE_SELECT,
       
   144   GST_POLL_MODE_PSELECT,
       
   145   GST_POLL_MODE_POLL,
       
   146   GST_POLL_MODE_PPOLL,
       
   147   GST_POLL_MODE_WINDOWS
       
   148 } GstPollMode;
       
   149 
       
   150 struct _GstPoll
       
   151 {
       
   152   GstPollMode mode;
       
   153 
       
   154   GMutex *lock;
       
   155 
       
   156   GArray *fds;
       
   157   GArray *active_fds;
       
   158 #ifndef G_OS_WIN32
       
   159   GstPollFD control_read_fd;
       
   160   GstPollFD control_write_fd;
       
   161 #else
       
   162   GArray *active_fds_ignored;
       
   163 
       
   164   GArray *events;
       
   165   GArray *active_events;
       
   166 
       
   167   HANDLE wakeup_event;
       
   168 #endif
       
   169 
       
   170   gboolean controllable;
       
   171   gboolean new_controllable;
       
   172   gboolean waiting;
       
   173   gboolean flushing;
       
   174 };
       
   175 
       
   176 static gint
       
   177 find_index (GArray * array, GstPollFD * fd)
       
   178 {
       
   179 #ifndef G_OS_WIN32
       
   180  //struct pollfd *ifd;
       
   181 GstPollFD *ifd;
       
   182  
       
   183 #else
       
   184   WinsockFd *ifd;
       
   185 #endif
       
   186   guint i;
       
   187 
       
   188   /* start by assuming the index found in the fd is still valid */
       
   189   if (fd->idx >= 0 && fd->idx < array->len) {
       
   190 #ifndef G_OS_WIN32
       
   191 #ifndef __SYMBIAN32__
       
   192     ifd = &g_array_index (array, struct pollfd, fd->idx);
       
   193 #else    
       
   194     ifd = &g_array_index (array, GstPollFD, fd->idx);
       
   195 #endif    
       
   196 #else
       
   197     ifd = &g_array_index (array, WinsockFd, fd->idx);
       
   198 #endif
       
   199 
       
   200     if (ifd->fd == fd->fd) {
       
   201       return fd->idx;
       
   202     }
       
   203   }
       
   204 
       
   205   /* the pollfd array has changed and we need to lookup the fd again */
       
   206   for (i = 0; i < array->len; i++) {
       
   207 #ifndef G_OS_WIN32
       
   208 #ifndef __SYMBIAN32__
       
   209     ifd = &g_array_index (array, struct pollfd, i);
       
   210 #else    
       
   211     ifd = &g_array_index (array, GstPollFD, i);
       
   212 #endif    
       
   213 #else
       
   214     ifd = &g_array_index (array, WinsockFd, i);
       
   215 #endif
       
   216 
       
   217     if (ifd->fd == fd->fd) {
       
   218       fd->idx = (gint) i;
       
   219       return fd->idx;
       
   220     }
       
   221   }
       
   222 
       
   223   fd->idx = -1;
       
   224   return fd->idx;
       
   225 }
       
   226 
       
   227 #if !defined(HAVE_PPOLL) && defined(HAVE_POLL)
       
   228 /* check if all file descriptors will fit in an fd_set */
       
   229 static gboolean
       
   230 selectable_fds (const GstPoll * set)
       
   231 {
       
   232   guint i;
       
   233 
       
   234   for (i = 0; i < set->fds->len; i++) {
       
   235     struct pollfd *pfd = &g_array_index (set->fds, struct pollfd, i);
       
   236 
       
   237     if (pfd->fd >= FD_SETSIZE)
       
   238       return FALSE;
       
   239   }
       
   240 
       
   241   return TRUE;
       
   242 }
       
   243 
       
   244 /* check if the timeout will convert to a timeout value used for poll()
       
   245  * without a loss of precision
       
   246  */
       
   247 static gboolean
       
   248 pollable_timeout (GstClockTime timeout)
       
   249 {
       
   250   if (timeout == GST_CLOCK_TIME_NONE)
       
   251     return TRUE;
       
   252 
       
   253   /* not a nice multiple of milliseconds */
       
   254   if (timeout % 1000000)
       
   255     return FALSE;
       
   256 
       
   257   return TRUE;
       
   258 }
       
   259 #endif
       
   260 
       
   261 static GstPollMode
       
   262 choose_mode (const GstPoll * set, GstClockTime timeout)
       
   263 {
       
   264   GstPollMode mode;
       
   265 
       
   266   if (set->mode == GST_POLL_MODE_AUTO) {
       
   267 #ifdef HAVE_PPOLL
       
   268     mode = GST_POLL_MODE_PPOLL;
       
   269 #elif defined(HAVE_POLL)
       
   270     if (!selectable_fds (set) || pollable_timeout (timeout)) {
       
   271       mode = GST_POLL_MODE_POLL;
       
   272     } else {
       
   273 #ifdef HAVE_PSELECT
       
   274       mode = GST_POLL_MODE_PSELECT;
       
   275 #else
       
   276       mode = GST_POLL_MODE_SELECT;
       
   277 #endif
       
   278     }
       
   279 #elif defined(HAVE_PSELECT)
       
   280     mode = GST_POLL_MODE_PSELECT;
       
   281 #else
       
   282     mode = GST_POLL_MODE_SELECT;
       
   283 #endif
       
   284   } else {
       
   285     mode = set->mode;
       
   286   }
       
   287   return mode;
       
   288 }
       
   289 
       
   290 #ifndef G_OS_WIN32
       
   291 static gint
       
   292 pollfd_to_fd_set (GstPoll * set, fd_set * readfds, fd_set * writefds)
       
   293 {
       
   294   gint max_fd = -1;
       
   295   guint i;
       
   296 
       
   297   FD_ZERO (readfds);
       
   298   FD_ZERO (writefds);
       
   299 
       
   300   g_mutex_lock (set->lock);
       
   301   
       
   302   for (i = 0; i < set->active_fds->len; i++) {
       
   303 #ifndef __SYMBIAN32__ 
       
   304     struct pollfd *pfd = &g_array_index (set->fds, struct pollfd, i);
       
   305 #else    
       
   306     GPollFD *pfd = &g_array_index (set->fds, GPollFD, i);
       
   307 #endif    
       
   308 
       
   309     if (pfd->fd < FD_SETSIZE) {
       
   310       if (pfd->events & POLLIN)
       
   311         FD_SET (pfd->fd, readfds);
       
   312       if (pfd->events & POLLOUT)
       
   313         FD_SET (pfd->fd, writefds);
       
   314       if (pfd->fd > max_fd)
       
   315         max_fd = pfd->fd;
       
   316     }
       
   317   }
       
   318 
       
   319     g_mutex_unlock (set->lock);
       
   320 
       
   321 
       
   322   return max_fd;
       
   323 }
       
   324 
       
   325 static void
       
   326 fd_set_to_pollfd (GstPoll * set, fd_set * readfds, fd_set * writefds)
       
   327 {
       
   328   guint i;
       
   329 
       
   330   g_mutex_lock (set->lock);
       
   331 
       
   332   for (i = 0; i < set->active_fds->len; i++) {
       
   333     //rj struct pollfd *pfd = &g_array_index (set->active_fds, struct pollfd, i);
       
   334     GPollFD *pfd = &g_array_index (set->active_fds, GPollFD, i);
       
   335 
       
   336     if (pfd->fd < FD_SETSIZE) {
       
   337       if (FD_ISSET (pfd->fd, readfds))
       
   338         pfd->revents |= POLLIN;
       
   339       if (FD_ISSET (pfd->fd, writefds))
       
   340         pfd->revents |= POLLOUT;
       
   341     }
       
   342   }
       
   343 
       
   344   g_mutex_unlock (set->lock);
       
   345 }
       
   346 #else /* G_OS_WIN32 */
       
   347 /*
       
   348  * Translate errors thrown by the Winsock API used by GstPoll:
       
   349  *   WSAEventSelect, WSAWaitForMultipleEvents and WSAEnumNetworkEvents
       
   350  */
       
   351 static gint
       
   352 gst_poll_winsock_error_to_errno (DWORD last_error)
       
   353 {
       
   354   switch (last_error) {
       
   355     case WSA_INVALID_HANDLE:
       
   356     case WSAEINVAL:
       
   357     case WSAENOTSOCK:
       
   358       return EBADF;
       
   359 
       
   360     case WSA_NOT_ENOUGH_MEMORY:
       
   361       return ENOMEM;
       
   362 
       
   363       /*
       
   364        * Anything else, including:
       
   365        *   WSA_INVALID_PARAMETER, WSAEFAULT, WSAEINPROGRESS, WSAENETDOWN,
       
   366        *   WSANOTINITIALISED
       
   367        */
       
   368     default:
       
   369       return EINVAL;
       
   370   }
       
   371 }
       
   372 
       
   373 static void
       
   374 gst_poll_free_winsock_event (GstPoll * set, gint idx)
       
   375 {
       
   376   WinsockFd *wfd = &g_array_index (set->fds, WinsockFd, idx);
       
   377   HANDLE event = g_array_index (set->events, HANDLE, idx);
       
   378 
       
   379   WSAEventSelect (wfd->fd, event, 0);
       
   380   CloseHandle (event);
       
   381 }
       
   382 
       
   383 static void
       
   384 gst_poll_update_winsock_event_mask (GstPoll * set, gint idx, glong flags,
       
   385     gboolean active)
       
   386 {
       
   387   WinsockFd *wfd;
       
   388 
       
   389   wfd = &g_array_index (set->fds, WinsockFd, idx);
       
   390 
       
   391   if (active)
       
   392     wfd->event_mask |= flags;
       
   393   else
       
   394     wfd->event_mask &= ~flags;
       
   395 
       
   396   /* reset ignored state if the new mask doesn't overlap at all */
       
   397   if ((wfd->ignored_event_mask & wfd->event_mask) == 0)
       
   398     wfd->ignored_event_mask = 0;
       
   399 }
       
   400 
       
   401 static gboolean
       
   402 gst_poll_prepare_winsock_active_sets (GstPoll * set)
       
   403 {
       
   404   guint i;
       
   405 
       
   406   g_array_set_size (set->active_fds, 0);
       
   407   g_array_set_size (set->active_fds_ignored, 0);
       
   408   g_array_set_size (set->active_events, 0);
       
   409   g_array_append_val (set->active_events, set->wakeup_event);
       
   410 
       
   411   for (i = 0; i < set->fds->len; i++) {
       
   412     WinsockFd *wfd = &g_array_index (set->fds, WinsockFd, i);
       
   413     HANDLE event = g_array_index (set->events, HANDLE, i);
       
   414 
       
   415     if (wfd->ignored_event_mask == 0) {
       
   416       gint ret;
       
   417 
       
   418       g_array_append_val (set->active_fds, *wfd);
       
   419       g_array_append_val (set->active_events, event);
       
   420 
       
   421       ret = WSAEventSelect (wfd->fd, event, wfd->event_mask);
       
   422       if (G_UNLIKELY (ret != 0)) {
       
   423         errno = gst_poll_winsock_error_to_errno (WSAGetLastError ());
       
   424         return FALSE;
       
   425       }
       
   426     } else {
       
   427       g_array_append_val (set->active_fds_ignored, wfd);
       
   428     }
       
   429   }
       
   430 
       
   431   return TRUE;
       
   432 }
       
   433 
       
   434 static gint
       
   435 gst_poll_collect_winsock_events (GstPoll * set)
       
   436 {
       
   437   gint res, i;
       
   438 
       
   439   /*
       
   440    * We need to check which events are signaled, and call
       
   441    * WSAEnumNetworkEvents for those that are, which resets
       
   442    * the event and clears the internal network event records.
       
   443    */
       
   444   res = 0;
       
   445   for (i = 0; i < set->active_fds->len; i++) {
       
   446     WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, i);
       
   447     HANDLE event = g_array_index (set->active_events, HANDLE, i + 1);
       
   448     DWORD wait_ret;
       
   449 
       
   450     wait_ret = WaitForSingleObject (event, 0);
       
   451     if (wait_ret == WAIT_OBJECT_0) {
       
   452       gint enum_ret = WSAEnumNetworkEvents (wfd->fd, event, &wfd->events);
       
   453 
       
   454       if (G_UNLIKELY (enum_ret != 0)) {
       
   455         res = -1;
       
   456         errno = gst_poll_winsock_error_to_errno (WSAGetLastError ());
       
   457         break;
       
   458       }
       
   459 
       
   460       res++;
       
   461     } else {
       
   462       /* clear any previously stored result */
       
   463       memset (&wfd->events, 0, sizeof (wfd->events));
       
   464     }
       
   465   }
       
   466 
       
   467   /* If all went well we also need to reset the ignored fds. */
       
   468   if (res >= 0) {
       
   469     res += set->active_fds_ignored->len;
       
   470 
       
   471     for (i = 0; i < set->active_fds_ignored->len; i++) {
       
   472       WinsockFd *wfd = g_array_index (set->active_fds_ignored, WinsockFd *, i);
       
   473 
       
   474       wfd->ignored_event_mask = 0;
       
   475     }
       
   476 
       
   477     g_array_set_size (set->active_fds_ignored, 0);
       
   478   }
       
   479 
       
   480   return res;
       
   481 }
       
   482 #endif
       
   483 
       
   484 /**
       
   485  * gst_poll_new:
       
   486  * @controllable: whether it should be possible to control a wait.
       
   487  *
       
   488  * Create a new file descriptor set. If @controllable, it
       
   489  * is possible to restart or flush a call to gst_poll_wait() with
       
   490  * gst_poll_restart() and gst_poll_set_flushing() respectively.
       
   491  *
       
   492  * Returns: a new #GstPoll, or %NULL in case of an error. Free with
       
   493  * gst_poll_free().
       
   494  *
       
   495  * Since: 0.10.18
       
   496  */
       
   497 #ifdef __SYMBIAN32__
       
   498 EXPORT_C
       
   499 #endif
       
   500 
       
   501  GstPoll *gst_poll_new (gboolean controllable)
       
   502 {
       
   503   GstPoll *nset;
       
   504 
       
   505   nset = g_new0 (GstPoll, 1);
       
   506   nset->lock = g_mutex_new ();
       
   507 #ifndef G_OS_WIN32
       
   508   nset->mode = GST_POLL_MODE_AUTO;
       
   509   //rj nset->fds = g_array_new (FALSE, FALSE, sizeof (struct pollfd));
       
   510   //rj nset->active_fds = g_array_new (FALSE, FALSE, sizeof (struct pollfd));
       
   511   nset->fds = g_array_new (FALSE, FALSE, sizeof (GstPollFD));
       
   512   nset->active_fds = g_array_new (FALSE, FALSE, sizeof (GstPollFD));
       
   513   nset->control_read_fd.fd = -1;
       
   514   nset->control_write_fd.fd = -1;
       
   515 #else
       
   516   nset->mode = GST_POLL_MODE_WINDOWS;
       
   517   nset->fds = g_array_new (FALSE, FALSE, sizeof (WinsockFd));
       
   518   nset->active_fds = g_array_new (FALSE, FALSE, sizeof (WinsockFd));
       
   519   nset->active_fds_ignored = g_array_new (FALSE, FALSE, sizeof (WinsockFd *));
       
   520   nset->events = g_array_new (FALSE, FALSE, sizeof (HANDLE));
       
   521   nset->active_events = g_array_new (FALSE, FALSE, sizeof (HANDLE));
       
   522 
       
   523   nset->wakeup_event = CreateEvent (NULL, TRUE, FALSE, NULL);
       
   524 #endif
       
   525 
       
   526   if (!gst_poll_set_controllable (nset, controllable))
       
   527     goto not_controllable;
       
   528 
       
   529   return nset;
       
   530 
       
   531   /* ERRORS */
       
   532 not_controllable:
       
   533   {
       
   534     gst_poll_free (nset);
       
   535     return NULL;
       
   536   }
       
   537 }
       
   538 
       
   539 /**
       
   540  * gst_poll_free:
       
   541  * @set: a file descriptor set.
       
   542  *
       
   543  * Free a file descriptor set.
       
   544  *
       
   545  * Since: 0.10.18
       
   546  */
       
   547 #ifdef __SYMBIAN32__
       
   548 EXPORT_C
       
   549 #endif
       
   550 
       
   551 void gst_poll_free (GstPoll * set)
       
   552 {
       
   553   g_return_if_fail (set != NULL);
       
   554 
       
   555 #ifndef G_OS_WIN32
       
   556   if (set->control_write_fd.fd >= 0)
       
   557     close (set->control_write_fd.fd);
       
   558   if (set->control_read_fd.fd >= 0)
       
   559     close (set->control_read_fd.fd);
       
   560 #else
       
   561   CloseHandle (set->wakeup_event);
       
   562 
       
   563   {
       
   564     guint i;
       
   565 
       
   566     for (i = 0; i < set->events->len; i++)
       
   567       gst_poll_free_winsock_event (set, i);
       
   568   }
       
   569 
       
   570   g_array_free (set->active_events, TRUE);
       
   571   g_array_free (set->events, TRUE);
       
   572   g_array_free (set->active_fds_ignored, TRUE);
       
   573 #endif
       
   574 
       
   575   g_array_free (set->active_fds, TRUE);
       
   576   g_array_free (set->fds, TRUE);
       
   577   g_mutex_free (set->lock);
       
   578   g_free (set);
       
   579 }
       
   580 
       
   581 /**
       
   582  * gst_poll_fd_init:
       
   583  * @fd: a #GstPollFD
       
   584  *
       
   585  * Initializes @fd. Alternatively you can initialize it with
       
   586  * #GST_POLL_FD_INIT.
       
   587  *
       
   588  * Since: 0.10.18
       
   589  */
       
   590 #ifdef __SYMBIAN32__
       
   591 EXPORT_C
       
   592 #endif
       
   593 
       
   594  void gst_poll_fd_init (GstPollFD * fd)
       
   595 {
       
   596   g_return_if_fail (fd != NULL);
       
   597 
       
   598   fd->fd = -1;
       
   599   fd->idx = -1;
       
   600 }
       
   601 
       
   602 static gboolean
       
   603 gst_poll_add_fd_unlocked (GstPoll * set, GstPollFD * fd)
       
   604 {
       
   605   gint idx;
       
   606 
       
   607   idx = find_index (set->fds, fd);
       
   608   if (idx < 0) {
       
   609 #ifndef G_OS_WIN32
       
   610    //rj struct pollfd nfd;
       
   611   GPollFD nfd;
       
   612     
       
   613     nfd.fd = fd->fd;
       
   614 #ifndef __SYMBIAN32__
       
   615     nfd.events = POLLERR | POLLNVAL | POLLHUP;   
       
   616 #else
       
   617     nfd.events = POLLERR | POLLNVAL ; 
       
   618 #endif
       
   619     nfd.revents = 0;
       
   620 
       
   621     g_array_append_val (set->fds, nfd);
       
   622 
       
   623     fd->idx = set->fds->len - 1;
       
   624 #else
       
   625     WinsockFd wfd;
       
   626     HANDLE event;
       
   627 
       
   628     wfd.fd = fd->fd;
       
   629     wfd.event_mask = FD_CLOSE;
       
   630     memset (&wfd.events, 0, sizeof (wfd.events));
       
   631     wfd.ignored_event_mask = 0;
       
   632     event = WSACreateEvent ();
       
   633 
       
   634     g_array_append_val (set->fds, wfd);
       
   635     g_array_append_val (set->events, event);
       
   636 
       
   637     fd->idx = set->fds->len - 1;
       
   638 #endif
       
   639   }
       
   640 
       
   641   return TRUE;
       
   642 }
       
   643 
       
   644 /**
       
   645  * gst_poll_add_fd:
       
   646  * @set: a file descriptor set.
       
   647  * @fd: a file descriptor.
       
   648  *
       
   649  * Add a file descriptor to the file descriptor set.
       
   650  *
       
   651  * Returns: %TRUE if the file descriptor was successfully added to the set.
       
   652  *
       
   653  * Since: 0.10.18
       
   654  */
       
   655 #ifdef __SYMBIAN32__
       
   656 EXPORT_C
       
   657 #endif
       
   658 
       
   659  gboolean gst_poll_add_fd (GstPoll * set, GstPollFD * fd)
       
   660 {
       
   661   gboolean ret;
       
   662 
       
   663   g_return_val_if_fail (set != NULL, FALSE);
       
   664   g_return_val_if_fail (fd != NULL, FALSE);
       
   665   g_return_val_if_fail (fd->fd >= 0, FALSE);
       
   666 
       
   667   g_mutex_lock (set->lock);
       
   668 
       
   669   ret = gst_poll_add_fd_unlocked (set, fd);
       
   670 
       
   671   g_mutex_unlock (set->lock);
       
   672 
       
   673   return ret;
       
   674 }
       
   675 
       
   676 /**
       
   677  * gst_poll_remove_fd:
       
   678  * @set: a file descriptor set.
       
   679  * @fd: a file descriptor.
       
   680  *
       
   681  * Remove a file descriptor from the file descriptor set.
       
   682  *
       
   683  * Returns: %TRUE if the file descriptor was successfully removed from the set.
       
   684  *
       
   685  * Since: 0.10.18
       
   686  */
       
   687 #ifdef __SYMBIAN32__
       
   688 EXPORT_C
       
   689 #endif
       
   690 
       
   691 gboolean gst_poll_remove_fd (GstPoll * set, GstPollFD * fd)
       
   692 {
       
   693   gint idx;
       
   694 
       
   695   g_return_val_if_fail (set != NULL, FALSE);
       
   696   g_return_val_if_fail (fd != NULL, FALSE);
       
   697   g_return_val_if_fail (fd->fd >= 0, FALSE);
       
   698 
       
   699   g_mutex_lock (set->lock);
       
   700 
       
   701   /* get the index, -1 is an fd that is not added */
       
   702   idx = find_index (set->fds, fd);
       
   703   if (idx >= 0) {
       
   704 #ifdef G_OS_WIN32
       
   705     gst_poll_free_winsock_event (set, idx);
       
   706     g_array_remove_index_fast (set->events, idx);
       
   707 #endif
       
   708 
       
   709     /* remove the fd at index, we use _remove_index_fast, which copies the last
       
   710      * element of the array to the freed index */
       
   711     g_array_remove_index_fast (set->fds, idx);
       
   712 
       
   713     /* mark fd as removed by setting the index to -1 */
       
   714     fd->idx = -1;
       
   715   }
       
   716 
       
   717   g_mutex_unlock (set->lock);
       
   718 
       
   719   return idx >= 0;
       
   720 }
       
   721 
       
   722 /**
       
   723  * gst_poll_fd_ctl_write:
       
   724  * @set: a file descriptor set.
       
   725  * @fd: a file descriptor.
       
   726  * @active: a new status.
       
   727  *
       
   728  * Control whether the descriptor @fd in @set will be monitored for
       
   729  * writability.
       
   730  *
       
   731  * Returns: %TRUE if the descriptor was successfully updated.
       
   732  *
       
   733  * Since: 0.10.18
       
   734  */
       
   735 #ifdef __SYMBIAN32__
       
   736 EXPORT_C
       
   737 #endif
       
   738 
       
   739 gboolean gst_poll_fd_ctl_write (GstPoll * set, GstPollFD * fd, gboolean active)
       
   740 {
       
   741   gint idx;
       
   742 
       
   743   g_return_val_if_fail (set != NULL, FALSE);
       
   744   g_return_val_if_fail (fd != NULL, FALSE);
       
   745   g_return_val_if_fail (fd->fd >= 0, FALSE);
       
   746 
       
   747   g_mutex_lock (set->lock);
       
   748 
       
   749   idx = find_index (set->fds, fd);
       
   750   if (idx >= 0) {
       
   751 #ifndef G_OS_WIN32
       
   752     // rj struct pollfd *pfd = &g_array_index (set->fds, struct pollfd, idx);
       
   753     GPollFD *pfd = &g_array_index (set->fds, GPollFD, idx);
       
   754     if (active)
       
   755       pfd->events |= POLLOUT;
       
   756     else
       
   757       pfd->events &= ~POLLOUT;
       
   758 #else
       
   759     gst_poll_update_winsock_event_mask (set, idx, FD_WRITE, active);
       
   760 #endif
       
   761   }
       
   762 
       
   763   g_mutex_unlock (set->lock);
       
   764 
       
   765   return idx >= 0;
       
   766 }
       
   767 
       
   768 static gboolean
       
   769 gst_poll_fd_ctl_read_unlocked (GstPoll * set, GstPollFD * fd, gboolean active)
       
   770 {
       
   771   gint idx;
       
   772 
       
   773   idx = find_index (set->fds, fd);
       
   774 
       
   775   if (idx >= 0) {
       
   776 #ifndef G_OS_WIN32
       
   777    //rj struct pollfd *pfd = &g_array_index (set->fds, struct pollfd, idx);
       
   778   GPollFD *pfd = &g_array_index (set->fds, GPollFD, idx);
       
   779     
       
   780 
       
   781     if (active)
       
   782         {
       
   783 #ifndef __SYMBIAN32__
       
   784             pfd->events |= (POLLIN | POLLPRI);
       
   785 #else
       
   786             pfd->events |= (POLLIN );
       
   787 #endif            
       
   788         }
       
   789     else
       
   790       pfd->events &= ~(POLLIN | POLLPRI);
       
   791 #else
       
   792     gst_poll_update_winsock_event_mask (set, idx, FD_READ | FD_ACCEPT, active);
       
   793 #endif
       
   794   }
       
   795 
       
   796   return idx >= 0;
       
   797 }
       
   798 
       
   799 /**
       
   800  * gst_poll_fd_ctl_read:
       
   801  * @set: a file descriptor set.
       
   802  * @fd: a file descriptor.
       
   803  * @active: a new status.
       
   804  *
       
   805  * Control whether the descriptor @fd in @set will be monitored for
       
   806  * readability.
       
   807  *
       
   808  * Returns: %TRUE if the descriptor was successfully updated.
       
   809  *
       
   810  * Since: 0.10.18
       
   811  */
       
   812 #ifdef __SYMBIAN32__
       
   813 EXPORT_C
       
   814 #endif
       
   815  gboolean gst_poll_fd_ctl_read (GstPoll * set, GstPollFD * fd, gboolean active)
       
   816 {
       
   817   gboolean ret;
       
   818 
       
   819   g_return_val_if_fail (set != NULL, FALSE);
       
   820   g_return_val_if_fail (fd != NULL, FALSE);
       
   821   g_return_val_if_fail (fd->fd >= 0, FALSE);
       
   822 
       
   823   g_mutex_lock (set->lock);
       
   824 
       
   825   ret = gst_poll_fd_ctl_read_unlocked (set, fd, active);
       
   826 
       
   827   g_mutex_unlock (set->lock);
       
   828 
       
   829   return ret;
       
   830 }
       
   831 
       
   832 /**
       
   833  * gst_poll_fd_ignored:
       
   834  * @set: a file descriptor set.
       
   835  * @fd: a file descriptor.
       
   836  *
       
   837  * Mark @fd as ignored so that the next call to gst_poll_wait() will yield
       
   838  * the same result for @fd as last time. This function must be called if no
       
   839  * operation (read/write/recv/send/etc.) will be performed on @fd before
       
   840  * the next call to gst_poll_wait().
       
   841  *
       
   842  * The reason why this is needed is because the underlying implementation
       
   843  * might not allow querying the fd more than once between calls to one of
       
   844  * the re-enabling operations.
       
   845  *
       
   846  * Since: 0.10.18
       
   847  */
       
   848 #ifdef __SYMBIAN32__
       
   849 EXPORT_C
       
   850 #endif
       
   851 
       
   852  void gst_poll_fd_ignored (GstPoll * set, GstPollFD * fd)
       
   853 {
       
   854 #ifdef G_OS_WIN32
       
   855   gint idx;
       
   856 
       
   857   g_return_if_fail (set != NULL);
       
   858   g_return_if_fail (fd != NULL);
       
   859   g_return_if_fail (fd->fd >= 0);
       
   860 
       
   861   g_mutex_lock (set->lock);
       
   862 
       
   863   idx = find_index (set->fds, fd);
       
   864   if (idx >= 0) {
       
   865     WinsockFd *wfd = &g_array_index (set->fds, WinsockFd, idx);
       
   866 
       
   867     wfd->ignored_event_mask = wfd->event_mask & (FD_READ | FD_WRITE);
       
   868   }
       
   869 
       
   870   g_mutex_unlock (set->lock);
       
   871 #endif
       
   872 }
       
   873 
       
   874 /**
       
   875  * gst_poll_fd_has_closed:
       
   876  * @set: a file descriptor set.
       
   877  * @fd: a file descriptor.
       
   878  *
       
   879  * Check if @fd in @set has closed the connection.
       
   880  *
       
   881  * Returns: %TRUE if the connection was closed.
       
   882  *
       
   883  * Since: 0.10.18
       
   884  */
       
   885 #ifdef __SYMBIAN32__
       
   886 EXPORT_C
       
   887 #endif
       
   888 
       
   889  gboolean gst_poll_fd_has_closed (const GstPoll * set, GstPollFD * fd)
       
   890 {
       
   891   gboolean res = FALSE;
       
   892   gint idx;
       
   893 
       
   894   g_return_val_if_fail (set != NULL, FALSE);
       
   895   g_return_val_if_fail (fd != NULL, FALSE);
       
   896   g_return_val_if_fail (fd->fd >= 0, FALSE);
       
   897 
       
   898   g_mutex_lock (set->lock);
       
   899 
       
   900   idx = find_index (set->active_fds, fd);
       
   901   if (idx >= 0) {
       
   902 #ifndef G_OS_WIN32
       
   903    //rj struct pollfd *pfd = &g_array_index (set->active_fds, struct pollfd, idx);
       
   904   GPollFD *pfd = &g_array_index (set->active_fds, GPollFD, idx);
       
   905  #ifndef __SYMBIAN32__ 
       
   906    res = (pfd->revents & POLLHUP) != 0;
       
   907  #else
       
   908  		res =  (pfd->revents & POLLHUP) == POLLHUP;
       
   909  #endif
       
   910  
       
   911 #else
       
   912     WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, idx);
       
   913 
       
   914     res = (wfd->events.lNetworkEvents & FD_CLOSE) != 0;
       
   915 #endif
       
   916   }
       
   917 
       
   918   g_mutex_unlock (set->lock);
       
   919 
       
   920   return res;
       
   921 }
       
   922 
       
   923 /**
       
   924  * gst_poll_fd_has_error:
       
   925  * @set: a file descriptor set.
       
   926  * @fd: a file descriptor.
       
   927  *
       
   928  * Check if @fd in @set has an error.
       
   929  *
       
   930  * Returns: %TRUE if the descriptor has an error.
       
   931  *
       
   932  * Since: 0.10.18
       
   933  */
       
   934 #ifdef __SYMBIAN32__
       
   935 EXPORT_C
       
   936 #endif
       
   937 
       
   938 gboolean gst_poll_fd_has_error (const GstPoll * set, GstPollFD * fd)
       
   939 {
       
   940   gboolean res = FALSE;
       
   941   gint idx;
       
   942 
       
   943   g_return_val_if_fail (set != NULL, FALSE);
       
   944   g_return_val_if_fail (fd != NULL, FALSE);
       
   945   g_return_val_if_fail (fd->fd >= 0, FALSE);
       
   946 
       
   947   g_mutex_lock (set->lock);
       
   948 
       
   949   idx = find_index (set->active_fds, fd);
       
   950   if (idx >= 0) {
       
   951 #ifndef G_OS_WIN32
       
   952     //rj struct pollfd *pfd = &g_array_index (set->active_fds, struct pollfd, idx);
       
   953   GPollFD *pfd = &g_array_index (set->active_fds, GPollFD, idx);
       
   954 
       
   955     res = (pfd->revents & (POLLERR | POLLNVAL)) != 0;
       
   956 #else
       
   957     WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, idx);
       
   958 
       
   959     res = (wfd->events.iErrorCode[FD_CLOSE_BIT] != 0) ||
       
   960         (wfd->events.iErrorCode[FD_READ_BIT] != 0) ||
       
   961         (wfd->events.iErrorCode[FD_WRITE_BIT] != 0) ||
       
   962         (wfd->events.iErrorCode[FD_ACCEPT_BIT] != 0);
       
   963 #endif
       
   964   }
       
   965 
       
   966   g_mutex_unlock (set->lock);
       
   967 
       
   968   return res;
       
   969 }
       
   970 
       
   971 static gboolean
       
   972 gst_poll_fd_can_read_unlocked (const GstPoll * set, GstPollFD * fd)
       
   973 {
       
   974   gboolean res = FALSE;
       
   975   gint idx;
       
   976 
       
   977   idx = find_index (set->active_fds, fd);
       
   978   if (idx >= 0) {
       
   979 #ifndef G_OS_WIN32
       
   980     //rj struct pollfd *pfd = &g_array_index (set->active_fds, struct pollfd, idx);
       
   981     GPollFD *pfd = &g_array_index (set->active_fds, GPollFD, idx);
       
   982 
       
   983     res = (pfd->revents & (POLLIN | POLLPRI)) != 0;
       
   984 #else
       
   985     WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, idx);
       
   986 
       
   987     res = (wfd->events.lNetworkEvents & (FD_READ | FD_ACCEPT)) != 0;
       
   988 #endif
       
   989   }
       
   990 
       
   991   return res;
       
   992 }
       
   993 
       
   994 /**
       
   995  * gst_poll_fd_can_read:
       
   996  * @set: a file descriptor set.
       
   997  * @fd: a file descriptor.
       
   998  *
       
   999  * Check if @fd in @set has data to be read.
       
  1000  *
       
  1001  * Returns: %TRUE if the descriptor has data to be read.
       
  1002  *
       
  1003  * Since: 0.10.18
       
  1004  */
       
  1005 #ifdef __SYMBIAN32__
       
  1006 EXPORT_C
       
  1007 #endif
       
  1008 
       
  1009 gboolean gst_poll_fd_can_read (const GstPoll * set, GstPollFD * fd)
       
  1010 {
       
  1011   gboolean res = FALSE;
       
  1012 
       
  1013   g_return_val_if_fail (set != NULL, FALSE);
       
  1014   g_return_val_if_fail (fd != NULL, FALSE);
       
  1015   g_return_val_if_fail (fd->fd >= 0, FALSE);
       
  1016 
       
  1017   g_mutex_lock (set->lock);
       
  1018 
       
  1019   res = gst_poll_fd_can_read_unlocked (set, fd);
       
  1020 
       
  1021   g_mutex_unlock (set->lock);
       
  1022 
       
  1023   return res;
       
  1024 }
       
  1025 
       
  1026 /**
       
  1027  * gst_poll_fd_can_write:
       
  1028  * @set: a file descriptor set.
       
  1029  * @fd: a file descriptor.
       
  1030  *
       
  1031  * Check if @fd in @set can be used for writing.
       
  1032  *
       
  1033  * Returns: %TRUE if the descriptor can be used for writing.
       
  1034  *
       
  1035  * Since: 0.10.18
       
  1036  */
       
  1037 #ifdef __SYMBIAN32__
       
  1038 EXPORT_C
       
  1039 #endif
       
  1040 
       
  1041 gboolean gst_poll_fd_can_write (const GstPoll * set, GstPollFD * fd)
       
  1042 {
       
  1043   gboolean res = FALSE;
       
  1044   gint idx;
       
  1045 
       
  1046   g_return_val_if_fail (set != NULL, FALSE);
       
  1047   g_return_val_if_fail (fd != NULL, FALSE);
       
  1048   g_return_val_if_fail (fd->fd >= 0, FALSE);
       
  1049 
       
  1050   g_mutex_lock (set->lock);
       
  1051 
       
  1052   idx = find_index (set->active_fds, fd);
       
  1053   if (idx >= 0) {
       
  1054 #ifndef G_OS_WIN32
       
  1055     //rj struct pollfd *pfd = &g_array_index (set->active_fds, struct pollfd, idx);
       
  1056     GPollFD *pfd = &g_array_index (set->active_fds, GPollFD, idx);
       
  1057 
       
  1058    //rj res = (pfd->revents & POLLOUT) != 0;
       
  1059     res = (pfd->revents & POLLOUT) != 0;
       
  1060 #else
       
  1061     WinsockFd *wfd = &g_array_index (set->active_fds, WinsockFd, idx);
       
  1062 
       
  1063     res = (wfd->events.lNetworkEvents & FD_WRITE) != 0;
       
  1064 #endif
       
  1065   }
       
  1066 
       
  1067   g_mutex_unlock (set->lock);
       
  1068 
       
  1069   return res;
       
  1070 }
       
  1071 
       
  1072 static void
       
  1073 gst_poll_check_ctrl_commands (GstPoll * set, gint res, gboolean * restarting)
       
  1074 {
       
  1075   /* check if the poll/select was aborted due to a command */
       
  1076   if (set->controllable) {
       
  1077 #ifndef G_OS_WIN32
       
  1078     while (TRUE) {
       
  1079       guchar cmd;
       
  1080       gint result;
       
  1081 
       
  1082       /* we do not check the read status of the control socket here because
       
  1083        * there may have been a write to the socket between the time the
       
  1084        * poll/select finished and before we got the mutex back, and we need
       
  1085        * to clear out the control socket before leaving */
       
  1086       READ_COMMAND (set, cmd, result);
       
  1087       if (result <= 0) {
       
  1088         /* no more commands, quit the loop */
       
  1089         break;
       
  1090       }
       
  1091 
       
  1092       /* if the control socket is the only socket with activity when we get
       
  1093        * here, we restart the _wait operation, else we allow the caller to
       
  1094        * process the other file descriptors */
       
  1095       if (res == 1 &&
       
  1096           gst_poll_fd_can_read_unlocked (set, &set->control_read_fd))
       
  1097         *restarting = TRUE;
       
  1098     }
       
  1099 #else
       
  1100     if (WaitForSingleObject (set->wakeup_event, 0) == WAIT_OBJECT_0) {
       
  1101       ResetEvent (set->wakeup_event);
       
  1102       *restarting = TRUE;
       
  1103     }
       
  1104 #endif
       
  1105   }
       
  1106 }
       
  1107 
       
  1108 /**
       
  1109  * gst_poll_wait:
       
  1110  * @set: a #GstPoll.
       
  1111  * @timeout: a timeout in nanoseconds.
       
  1112  *
       
  1113  * Wait for activity on the file descriptors in @set. This function waits up to
       
  1114  * the specified @timeout.  A timeout of #GST_CLOCK_TIME_NONE waits forever.
       
  1115  *
       
  1116  * When this function is called from multiple threads, -1 will be returned with
       
  1117  * errno set to EPERM.
       
  1118  *
       
  1119  * Returns: The number of #GstPollFD in @set that have activity or 0 when no
       
  1120  * activity was detected after @timeout. If an error occurs, -1 is returned
       
  1121  * and errno is set.
       
  1122  *
       
  1123  * Since: 0.10.18
       
  1124  */
       
  1125 #ifdef __SYMBIAN32__
       
  1126 EXPORT_C
       
  1127 #endif
       
  1128 
       
  1129 gint gst_poll_wait (GstPoll * set, GstClockTime timeout)
       
  1130 {
       
  1131   gboolean restarting;
       
  1132   int res = -1;
       
  1133 
       
  1134   g_return_val_if_fail (set != NULL, -1);
       
  1135 
       
  1136   g_mutex_lock (set->lock);
       
  1137 
       
  1138   /* we cannot wait from multiple threads */
       
  1139   if (set->waiting)
       
  1140     goto already_waiting;
       
  1141 
       
  1142   /* flushing, exit immediatly */
       
  1143   if (set->flushing)
       
  1144     goto flushing;
       
  1145 
       
  1146   set->waiting = TRUE;
       
  1147 
       
  1148   do {
       
  1149     GstPollMode mode;
       
  1150 
       
  1151     res = -1;
       
  1152     restarting = FALSE;
       
  1153 
       
  1154     mode = choose_mode (set, timeout);
       
  1155 
       
  1156 #ifndef G_OS_WIN32
       
  1157     g_array_set_size (set->active_fds, set->fds->len);
       
  1158    //rj memcpy (set->active_fds->data, set->fds->data,
       
  1159    //     set->fds->len * sizeof (struct pollfd));
       
  1160     memcpy (set->active_fds->data, set->fds->data,
       
  1161            set->fds->len * sizeof (GstPollFD));
       
  1162 #else
       
  1163     if (!gst_poll_prepare_winsock_active_sets (set))
       
  1164       goto winsock_error;
       
  1165 #endif
       
  1166 
       
  1167     g_mutex_unlock (set->lock);
       
  1168 
       
  1169     switch (mode) {
       
  1170       case GST_POLL_MODE_AUTO:
       
  1171         g_assert_not_reached ();
       
  1172         break;
       
  1173       case GST_POLL_MODE_PPOLL:
       
  1174       {
       
  1175 #ifdef HAVE_PPOLL
       
  1176         struct timespec ts;
       
  1177         struct timespec *tsptr;
       
  1178 
       
  1179         if (timeout != GST_CLOCK_TIME_NONE) {
       
  1180           GST_TIME_TO_TIMESPEC (timeout, ts);
       
  1181           tsptr = &ts;
       
  1182         } else {
       
  1183           tsptr = NULL;
       
  1184         }
       
  1185 
       
  1186         res =
       
  1187             ppoll ((struct pollfd *) set->active_fds->data,
       
  1188             set->active_fds->len, tsptr, NULL);
       
  1189 #else
       
  1190         g_assert_not_reached ();
       
  1191         errno = ENOSYS;
       
  1192 #endif
       
  1193         break;
       
  1194       }
       
  1195       case GST_POLL_MODE_POLL:
       
  1196       {
       
  1197 #ifdef HAVE_POLL
       
  1198         gint t;
       
  1199 
       
  1200         if (timeout != GST_CLOCK_TIME_NONE) {
       
  1201           t = GST_TIME_AS_MSECONDS (timeout);
       
  1202         } else {
       
  1203           t = -1;
       
  1204         }
       
  1205 
       
  1206         res =
       
  1207             poll ((struct pollfd *) set->active_fds->data,
       
  1208             set->active_fds->len, t);
       
  1209 #else
       
  1210         g_assert_not_reached ();
       
  1211         errno = ENOSYS;
       
  1212 #endif
       
  1213         break;
       
  1214       }
       
  1215       case GST_POLL_MODE_PSELECT:
       
  1216 #ifndef HAVE_PSELECT
       
  1217       {
       
  1218         g_assert_not_reached ();
       
  1219         errno = ENOSYS;
       
  1220         break;
       
  1221       }
       
  1222 #endif
       
  1223       case GST_POLL_MODE_SELECT:
       
  1224       {
       
  1225 #ifndef G_OS_WIN32
       
  1226         fd_set readfds;
       
  1227         fd_set writefds;
       
  1228         fd_set excepfds;
       
  1229         gint max_fd;
       
  1230 
       
  1231         max_fd = pollfd_to_fd_set (set, &readfds, &writefds);
       
  1232 
       
  1233         if (mode == GST_POLL_MODE_SELECT) {
       
  1234           struct timeval tv;
       
  1235           struct timeval *tvptr;
       
  1236 
       
  1237           if (timeout != GST_CLOCK_TIME_NONE) {
       
  1238             GST_TIME_TO_TIMEVAL (timeout, tv);
       
  1239             tvptr = &tv;
       
  1240           } else {
       
  1241             tvptr = NULL;
       
  1242           }
       
  1243 //temporary  fix for multifdsink  
       
  1244           FD_ZERO(&excepfds);
       
  1245          
       
  1246         if( max_fd != -1)
       
  1247          {
       
  1248           if( ! FD_ISSET(max_fd,&readfds))
       
  1249               {
       
  1250               if( ! FD_ISSET(max_fd,&writefds))
       
  1251                   {
       
  1252                   FD_SET(max_fd,&excepfds);
       
  1253                   }
       
  1254               }
       
  1255           }
       
  1256           
       
  1257           /*
       
  1258           if( max_fd != -1)
       
  1259           FD_SET(max_fd,&excepfds);
       
  1260           */
       
  1261 #ifdef __SYMBIAN32__
       
  1262           if( max_fd == -1 && !tvptr);
       
  1263           else
       
  1264               res = select (max_fd + 1, &readfds, &writefds, &excepfds, tvptr);
       
  1265 #else        
       
  1266           res = select (max_fd + 1, &readfds, &writefds, NULL, tvptr);
       
  1267 #endif        
       
  1268         } else {
       
  1269 #ifdef HAVE_PSELECT
       
  1270           struct timespec ts;
       
  1271           struct timespec *tsptr;
       
  1272 
       
  1273           if (timeout != GST_CLOCK_TIME_NONE) {
       
  1274             GST_TIME_TO_TIMESPEC (timeout, ts);
       
  1275             tsptr = &ts;
       
  1276           } else {
       
  1277             tsptr = NULL;
       
  1278           }
       
  1279 
       
  1280           res = pselect (max_fd + 1, &readfds, &writefds, NULL, tsptr, NULL);
       
  1281 #endif
       
  1282         }
       
  1283 
       
  1284         if (res > 0) {
       
  1285           fd_set_to_pollfd (set, &readfds, &writefds);
       
  1286         }
       
  1287 #else /* G_OS_WIN32 */
       
  1288         g_assert_not_reached ();
       
  1289         errno = ENOSYS;
       
  1290 #endif
       
  1291         break;
       
  1292       }
       
  1293       case GST_POLL_MODE_WINDOWS:
       
  1294       {
       
  1295 #ifdef G_OS_WIN32
       
  1296         gint ignore_count = set->active_fds_ignored->len;
       
  1297         DWORD t, wait_ret;
       
  1298 
       
  1299         if (G_LIKELY (ignore_count == 0)) {
       
  1300           if (timeout != GST_CLOCK_TIME_NONE)
       
  1301             t = GST_TIME_AS_MSECONDS (timeout);
       
  1302           else
       
  1303             t = INFINITE;
       
  1304         } else {
       
  1305           /* already one or more ignored fds, so we quickly sweep the others */
       
  1306           t = 0;
       
  1307         }
       
  1308 
       
  1309         wait_ret = WSAWaitForMultipleEvents (set->active_events->len,
       
  1310             (HANDLE *) set->active_events->data, FALSE, t, FALSE);
       
  1311 
       
  1312         if (ignore_count == 0 && wait_ret == WSA_WAIT_TIMEOUT) {
       
  1313           res = 0;
       
  1314         } else if (wait_ret == WSA_WAIT_FAILED) {
       
  1315           res = -1;
       
  1316           errno = gst_poll_winsock_error_to_errno (WSAGetLastError ());
       
  1317         } else {
       
  1318           /* the first entry is the wakeup event */
       
  1319           if (wait_ret - WSA_WAIT_EVENT_0 >= 1) {
       
  1320             res = gst_poll_collect_winsock_events (set);
       
  1321           } else {
       
  1322             res = 1;            /* wakeup event */
       
  1323           }
       
  1324         }
       
  1325 #else
       
  1326         g_assert_not_reached ();
       
  1327         errno = ENOSYS;
       
  1328 #endif
       
  1329         break;
       
  1330       }
       
  1331     }
       
  1332 
       
  1333     g_mutex_lock (set->lock);
       
  1334 
       
  1335     gst_poll_check_ctrl_commands (set, res, &restarting);
       
  1336 
       
  1337     /* update the controllable state if needed */
       
  1338     set->controllable = set->new_controllable;
       
  1339 
       
  1340     if (set->flushing) {
       
  1341       /* we got woken up and we are flushing, we need to stop */
       
  1342       errno = EBUSY;
       
  1343       res = -1;
       
  1344       break;
       
  1345     }
       
  1346   } while (restarting);
       
  1347 
       
  1348   set->waiting = FALSE;
       
  1349 
       
  1350   g_mutex_unlock (set->lock);
       
  1351 
       
  1352   return res;
       
  1353 
       
  1354   /* ERRORS */
       
  1355 already_waiting:
       
  1356   {
       
  1357     g_mutex_unlock (set->lock);
       
  1358     errno = EPERM;
       
  1359     return -1;
       
  1360   }
       
  1361 flushing:
       
  1362   {
       
  1363     g_mutex_unlock (set->lock);
       
  1364     errno = EBUSY;
       
  1365     return -1;
       
  1366   }
       
  1367 #ifdef G_OS_WIN32
       
  1368 winsock_error:
       
  1369   {
       
  1370     g_mutex_unlock (set->lock);
       
  1371     return -1;
       
  1372   }
       
  1373 #endif
       
  1374 }
       
  1375 
       
  1376 /**
       
  1377  * gst_poll_set_controllable:
       
  1378  * @set: a #GstPoll.
       
  1379  * @controllable: new controllable state.
       
  1380  *
       
  1381  * When @controllable is %TRUE, this function ensures that future calls to
       
  1382  * gst_poll_wait() will be affected by gst_poll_restart() and
       
  1383  * gst_poll_set_flushing().
       
  1384  *
       
  1385  * Returns: %TRUE if the controllability of @set could be updated.
       
  1386  *
       
  1387  * Since: 0.10.18
       
  1388  */
       
  1389 #ifdef __SYMBIAN32__
       
  1390 EXPORT_C
       
  1391 #endif
       
  1392 
       
  1393 gboolean gst_poll_set_controllable (GstPoll * set, gboolean controllable)
       
  1394 {
       
  1395   g_return_val_if_fail (set != NULL, FALSE);
       
  1396 
       
  1397   g_mutex_lock (set->lock);
       
  1398 
       
  1399 #ifndef G_OS_WIN32
       
  1400   if (controllable && set->control_read_fd.fd < 0) {
       
  1401     gint control_sock[2];
       
  1402 /* rj
       
  1403     if (socketpair (PF_UNIX, SOCK_STREAM, 0, control_sock) < 0)
       
  1404       goto no_socket_pair;
       
  1405 */
       
  1406     fcntl (control_sock[0], F_SETFL, O_NONBLOCK);
       
  1407     fcntl (control_sock[1], F_SETFL, O_NONBLOCK);
       
  1408 
       
  1409     set->control_read_fd.fd = control_sock[0];
       
  1410     set->control_write_fd.fd = control_sock[1];
       
  1411 
       
  1412     gst_poll_add_fd_unlocked (set, &set->control_read_fd);
       
  1413   }
       
  1414 
       
  1415   if (set->control_read_fd.fd >= 0)
       
  1416     gst_poll_fd_ctl_read_unlocked (set, &set->control_read_fd, controllable);
       
  1417 #endif
       
  1418 
       
  1419   /* delay the change of the controllable state if we are waiting */
       
  1420   set->new_controllable = controllable;
       
  1421   if (!set->waiting)
       
  1422     set->controllable = controllable;
       
  1423 
       
  1424   g_mutex_unlock (set->lock);
       
  1425 
       
  1426   return TRUE;
       
  1427 
       
  1428   /* ERRORS */
       
  1429 #ifndef G_OS_WIN32
       
  1430 no_socket_pair:
       
  1431   {
       
  1432     g_mutex_unlock (set->lock);
       
  1433     return FALSE;
       
  1434   }
       
  1435 #endif
       
  1436 }
       
  1437 
       
  1438 /**
       
  1439  * gst_poll_restart:
       
  1440  * @set: a #GstPoll.
       
  1441  *
       
  1442  * Restart any gst_poll_wait() that is in progress. This function is typically
       
  1443  * used after adding or removing descriptors to @set.
       
  1444  *
       
  1445  * If @set is not controllable, then this call will have no effect.
       
  1446  *
       
  1447  * Since: 0.10.18
       
  1448  */
       
  1449 #ifdef __SYMBIAN32__
       
  1450 EXPORT_C
       
  1451 #endif
       
  1452 
       
  1453 void gst_poll_restart (GstPoll * set)
       
  1454 {
       
  1455   g_return_if_fail (set != NULL);
       
  1456 
       
  1457   g_mutex_lock (set->lock);
       
  1458 
       
  1459   if (set->controllable && set->waiting) {
       
  1460 #ifndef G_OS_WIN32
       
  1461     /* if we are waiting, we can send the command, else we do not have to
       
  1462      * bother, future calls will automatically pick up the new fdset */
       
  1463     SEND_COMMAND (set, GST_POLL_CMD_WAKEUP);
       
  1464 #else
       
  1465     SetEvent (set->wakeup_event);
       
  1466 #endif
       
  1467   }
       
  1468 
       
  1469   g_mutex_unlock (set->lock);
       
  1470 }
       
  1471 
       
  1472 /**
       
  1473  * gst_poll_set_flushing:
       
  1474  * @set: a #GstPoll.
       
  1475  * @flushing: new flushing state.
       
  1476  *
       
  1477  * When @flushing is %TRUE, this function ensures that current and future calls
       
  1478  * to gst_poll_wait() will return -1, with errno set to EBUSY.
       
  1479  *
       
  1480  * Unsetting the flushing state will restore normal operation of @set.
       
  1481  *
       
  1482  * Since: 0.10.18
       
  1483  */
       
  1484 #ifdef __SYMBIAN32__
       
  1485 EXPORT_C
       
  1486 #endif
       
  1487 
       
  1488 void gst_poll_set_flushing (GstPoll * set, gboolean flushing)
       
  1489 {
       
  1490   g_return_if_fail (set != NULL);
       
  1491 
       
  1492   g_mutex_lock (set->lock);
       
  1493 
       
  1494   /* update the new state first */
       
  1495   set->flushing = flushing;
       
  1496 
       
  1497   if (flushing && set->controllable && set->waiting) {
       
  1498     /* we are flushing, controllable and waiting, wake up the waiter. When we
       
  1499      * stop the flushing operation we don't clear the wakeup fd here, this will
       
  1500      * happen in the _wait() thread. */
       
  1501 #ifndef G_OS_WIN32
       
  1502     SEND_COMMAND (set, GST_POLL_CMD_WAKEUP);
       
  1503 #else
       
  1504     SetEvent (set->wakeup_event);
       
  1505 #endif
       
  1506   }
       
  1507 
       
  1508   g_mutex_unlock (set->lock);
       
  1509 }