Пример #1
0
static void
soup_input_stream_prepare_for_io (GInputStream *stream,
				  GCancellable *cancellable,
				  guchar       *buffer,
				  gsize         count)
{
  SoupInputStreamPrivate *priv = SOUP_INPUT_STREAM_GET_PRIVATE (stream);
  int cancel_fd;

  priv->cancellable = cancellable;
  cancel_fd = g_cancellable_get_fd (cancellable);
  if (cancel_fd != -1)
    {
      GIOChannel *chan = g_io_channel_unix_new (cancel_fd);
      priv->cancel_watch = soup_add_io_watch (priv->async_context, chan,
					      G_IO_IN | G_IO_ERR | G_IO_HUP,
					      soup_input_stream_cancelled,
					      stream);
      g_io_channel_unref (chan);
    }

  priv->caller_buffer = buffer;
  priv->caller_bufsize = count;
  priv->caller_nread = 0;

  if (priv->got_headers)
    soup_session_unpause_message (priv->session, priv->msg);
}
Пример #2
0
static void
soup_output_stream_prepare_for_io (GOutputStream *stream, GCancellable *cancellable)
{
  SoupOutputStreamPrivate *priv = SOUP_OUTPUT_STREAM_GET_PRIVATE (stream);
  int cancel_fd;

  /* Move the buffer to the SoupMessage */
  soup_message_body_append (priv->msg->request_body, SOUP_MEMORY_TAKE,
			    priv->ba->data, priv->ba->len);
  g_byte_array_free (priv->ba, FALSE);
  priv->ba = NULL;

  /* Set up cancellation */
  priv->cancellable = cancellable;
  cancel_fd = g_cancellable_get_fd (cancellable);
  if (cancel_fd != -1)
    {
      GIOChannel *chan = g_io_channel_unix_new (cancel_fd);
      priv->cancel_watch = soup_add_io_watch (priv->async_context, chan,
					      G_IO_IN | G_IO_ERR | G_IO_HUP,
					      soup_output_stream_cancelled,
					      stream);
      g_io_channel_unref (chan);
    }

  /* Add an extra ref since soup_session_queue_message steals one */
  g_object_ref (priv->msg);
  soup_session_queue_message (priv->session, priv->msg, NULL, NULL);
}
Пример #3
0
/**
 * g_cancellable_make_pollfd:
 * @cancellable: a #GCancellable or %NULL
 * @pollfd: a pointer to a #GPollFD
 * 
 * Creates a #GPollFD corresponding to @cancellable; this can be passed
 * to g_poll() and used to poll for cancellation. This is useful both
 * for unix systems without a native poll and for portability to
 * windows.
 *
 * When this function returns %TRUE, you should use 
 * g_cancellable_release_fd() to free up resources allocated for the 
 * @pollfd. After a %FALSE return, do not call g_cancellable_release_fd().
 *
 * If this function returns %FALSE, either no @cancellable was given or
 * resource limits prevent this function from allocating the necessary 
 * structures for polling. (On Linux, you will likely have reached 
 * the maximum number of file descriptors.) The suggested way to handle
 * these cases is to ignore the @cancellable.
 *
 * You are not supposed to read from the fd yourself, just check for
 * readable status. Reading to unset the readable status is done
 * with g_cancellable_reset().
 *
 * Returns: %TRUE if @pollfd was successfully initialized, %FALSE on 
 *          failure to prepare the cancellable.
 * 
 * Since: 2.22
 **/
gboolean
g_cancellable_make_pollfd (GCancellable *cancellable, GPollFD *pollfd)
{
  g_return_val_if_fail (pollfd != NULL, FALSE);
  if (cancellable == NULL)
    return FALSE;
  g_return_val_if_fail (G_IS_CANCELLABLE (cancellable), FALSE);

  {
#ifdef G_OS_WIN32
    GCancellablePrivate *priv;

    priv = cancellable->priv;
    G_LOCK(cancellable);
    if (priv->event == NULL)
      {
        /* A manual reset anonymous event, starting unset */
        priv->event = CreateEvent (NULL, TRUE, FALSE, NULL);
        if (priv->event == NULL)
          {
            G_UNLOCK(cancellable);
            return FALSE;
          }
        if (priv->cancelled)
          SetEvent(priv->event);
      }
    priv->fd_refcount++;
    G_UNLOCK(cancellable);

    pollfd->fd = (gintptr)priv->event;
#else /* !G_OS_WIN32 */
    int fd = g_cancellable_get_fd (cancellable);

    if (fd == -1)
      return FALSE;
    pollfd->fd = fd;
#endif /* G_OS_WIN32 */
  }

  pollfd->events = G_IO_IN;
  pollfd->revents = 0;

  return TRUE;
}
Пример #4
0
static gssize
g_unix_output_stream_write (GOutputStream  *stream,
			    const void     *buffer,
			    gsize           count,
			    GCancellable   *cancellable,
			    GError        **error)
{
  GUnixOutputStream *unix_stream;
  gssize res;
  struct pollfd poll_fds[2];
  int poll_ret;
  int cancel_fd;

  unix_stream = G_UNIX_OUTPUT_STREAM (stream);

  cancel_fd = g_cancellable_get_fd (cancellable);
  if (cancel_fd != -1)
    {
      do
	{
	  poll_fds[0].events = POLLOUT;
	  poll_fds[0].fd = unix_stream->priv->fd;
	  poll_fds[1].events = POLLIN;
	  poll_fds[1].fd = cancel_fd;
	  poll_ret = poll (poll_fds, 2, -1);
	}
      while (poll_ret == -1 && errno == EINTR);
      
      if (poll_ret == -1)
	{
          int errsv = errno;

	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errsv),
		       _("Error writing to unix: %s"),
		       g_strerror (errsv));
	  return -1;
	}
    }
      
  while (1)
    {
      if (g_cancellable_set_error_if_cancelled (cancellable, error))
	return -1;

      res = write (unix_stream->priv->fd, buffer, count);
      if (res == -1)
	{
          int errsv = errno;

	  if (errsv == EINTR)
	    continue;
	  
	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errsv),
		       _("Error writing to unix: %s"),
		       g_strerror (errsv));
	}
      
      break;
    }
  
  return res;
}