~ubuntu-branches/debian/sid/glib2.0/sid

« back to all changes in this revision

Viewing changes to gio/gunixoutputstream.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2013-05-08 06:25:57 UTC
  • mfrom: (1.27.14) (3.1.181 experimental)
  • Revision ID: package-import@ubuntu.com-20130508062557-i7gbku66mls70gi2
Tags: 2.36.1-2
Merge experimental branch, upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
95
95
static gboolean g_unix_output_stream_close        (GOutputStream        *stream,
96
96
                                                   GCancellable         *cancellable,
97
97
                                                   GError              **error);
98
 
static void     g_unix_output_stream_write_async  (GOutputStream        *stream,
99
 
                                                   const void           *buffer,
100
 
                                                   gsize                 count,
101
 
                                                   int                   io_priority,
102
 
                                                   GCancellable         *cancellable,
103
 
                                                   GAsyncReadyCallback   callback,
104
 
                                                   gpointer              data);
105
 
static gssize   g_unix_output_stream_write_finish (GOutputStream        *stream,
106
 
                                                   GAsyncResult         *result,
107
 
                                                   GError              **error);
108
98
static void     g_unix_output_stream_close_async  (GOutputStream        *stream,
109
99
                                                   int                   io_priority,
110
100
                                                   GCancellable         *cancellable,
114
104
                                                   GAsyncResult         *result,
115
105
                                                   GError              **error);
116
106
 
 
107
static gboolean g_unix_output_stream_pollable_can_poll      (GPollableOutputStream *stream);
117
108
static gboolean g_unix_output_stream_pollable_is_writable   (GPollableOutputStream *stream);
118
109
static GSource *g_unix_output_stream_pollable_create_source (GPollableOutputStream *stream,
119
110
                                                             GCancellable         *cancellable);
138
129
 
139
130
  stream_class->write_fn = g_unix_output_stream_write;
140
131
  stream_class->close_fn = g_unix_output_stream_close;
141
 
  stream_class->write_async = g_unix_output_stream_write_async;
142
 
  stream_class->write_finish = g_unix_output_stream_write_finish;
143
132
  stream_class->close_async = g_unix_output_stream_close_async;
144
133
  stream_class->close_finish = g_unix_output_stream_close_finish;
145
134
 
177
166
static void
178
167
g_unix_output_stream_pollable_iface_init (GPollableOutputStreamInterface *iface)
179
168
{
 
169
  iface->can_poll = g_unix_output_stream_pollable_can_poll;
180
170
  iface->is_writable = g_unix_output_stream_pollable_is_writable;
181
171
  iface->create_source = g_unix_output_stream_pollable_create_source;
182
172
}
421
411
  if (!unix_stream->priv->close_fd)
422
412
    return TRUE;
423
413
  
424
 
  while (1)
 
414
  /* This might block during the close. Doesn't seem to be a way to avoid it though. */
 
415
  res = close (unix_stream->priv->fd);
 
416
  if (res == -1)
425
417
    {
426
 
      /* This might block during the close. Doesn't seem to be a way to avoid it though. */
427
 
      res = close (unix_stream->priv->fd);
428
 
      if (res == -1)
429
 
        {
430
 
          int errsv = errno;
 
418
      int errsv = errno;
431
419
 
432
 
          g_set_error (error, G_IO_ERROR,
433
 
                       g_io_error_from_errno (errsv),
434
 
                       _("Error closing file descriptor: %s"),
435
 
                       g_strerror (errsv));
436
 
        }
437
 
      break;
 
420
      g_set_error (error, G_IO_ERROR,
 
421
                   g_io_error_from_errno (errsv),
 
422
                   _("Error closing file descriptor: %s"),
 
423
                   g_strerror (errsv));
438
424
    }
439
425
 
440
426
  return res != -1;
441
427
}
442
428
 
443
 
typedef struct {
444
 
  gsize count;
445
 
  const void *buffer;
446
 
  GAsyncReadyCallback callback;
447
 
  gpointer user_data;
448
 
  GCancellable *cancellable;
449
 
  GUnixOutputStream *stream;
450
 
} WriteAsyncData;
451
 
 
452
 
static gboolean
453
 
write_async_cb (int             fd,
454
 
                GIOCondition    condition,
455
 
                WriteAsyncData *data)
456
 
{
457
 
  GSimpleAsyncResult *simple;
458
 
  GError *error = NULL;
459
 
  gssize count_written;
460
 
 
461
 
  while (1)
462
 
    {
463
 
      if (g_cancellable_set_error_if_cancelled (data->cancellable, &error))
464
 
        {
465
 
          count_written = -1;
466
 
          break;
467
 
        }
468
 
      
469
 
      count_written = write (data->stream->priv->fd, data->buffer, data->count);
470
 
      if (count_written == -1)
471
 
        {
472
 
          int errsv = errno;
473
 
 
474
 
          if (errsv == EINTR || errsv == EAGAIN)
475
 
            return TRUE;
476
 
          
477
 
          g_set_error (&error, G_IO_ERROR,
478
 
                       g_io_error_from_errno (errsv),
479
 
                       _("Error writing to file descriptor: %s"),
480
 
                       g_strerror (errsv));
481
 
        }
482
 
      break;
483
 
    }
484
 
 
485
 
  simple = g_simple_async_result_new (G_OBJECT (data->stream),
486
 
                                      data->callback,
487
 
                                      data->user_data,
488
 
                                      g_unix_output_stream_write_async);
489
 
  
490
 
  g_simple_async_result_set_op_res_gssize (simple, count_written);
491
 
 
492
 
  if (count_written == -1)
493
 
    g_simple_async_result_take_error (simple, error);
494
 
 
495
 
  /* Complete immediately, not in idle, since we're already in a mainloop callout */
496
 
  g_simple_async_result_complete (simple);
497
 
  g_object_unref (simple);
498
 
 
499
 
  return FALSE;
500
 
}
501
 
 
502
 
static void
503
 
g_unix_output_stream_write_async (GOutputStream       *stream,
504
 
                                  const void          *buffer,
505
 
                                  gsize                count,
506
 
                                  int                  io_priority,
507
 
                                  GCancellable        *cancellable,
508
 
                                  GAsyncReadyCallback  callback,
509
 
                                  gpointer             user_data)
510
 
{
511
 
  GSource *source;
512
 
  GUnixOutputStream *unix_stream;
513
 
  WriteAsyncData *data;
514
 
 
515
 
  unix_stream = G_UNIX_OUTPUT_STREAM (stream);
516
 
 
517
 
  if (!unix_stream->priv->is_pipe_or_socket)
518
 
    {
519
 
      G_OUTPUT_STREAM_CLASS (g_unix_output_stream_parent_class)->
520
 
        write_async (stream, buffer, count, io_priority,
521
 
                     cancellable, callback, user_data);
522
 
      return;
523
 
    }
524
 
 
525
 
  data = g_new0 (WriteAsyncData, 1);
526
 
  data->count = count;
527
 
  data->buffer = buffer;
528
 
  data->callback = callback;
529
 
  data->user_data = user_data;
530
 
  data->cancellable = cancellable;
531
 
  data->stream = unix_stream;
532
 
 
533
 
  source = _g_fd_source_new (unix_stream->priv->fd,
534
 
                             G_IO_OUT,
535
 
                             cancellable);
536
 
  g_source_set_name (source, "GUnixOutputStream");
537
 
  
538
 
  g_source_set_callback (source, (GSourceFunc)write_async_cb, data, g_free);
539
 
  g_source_attach (source, g_main_context_get_thread_default ());
540
 
  
541
 
  g_source_unref (source);
542
 
}
543
 
 
544
 
static gssize
545
 
g_unix_output_stream_write_finish (GOutputStream  *stream,
546
 
                                   GAsyncResult   *result,
547
 
                                   GError        **error)
548
 
{
549
 
  GUnixOutputStream *unix_stream = G_UNIX_OUTPUT_STREAM (stream);
550
 
  GSimpleAsyncResult *simple;
551
 
  gssize nwritten;
552
 
 
553
 
  if (!unix_stream->priv->is_pipe_or_socket)
554
 
    {
555
 
      return G_OUTPUT_STREAM_CLASS (g_unix_output_stream_parent_class)->
556
 
        write_finish (stream, result, error);
557
 
    }
558
 
 
559
 
  simple = G_SIMPLE_ASYNC_RESULT (result);
560
 
  g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_unix_output_stream_write_async);
561
 
  
562
 
  nwritten = g_simple_async_result_get_op_res_gssize (simple);
563
 
  return nwritten;
564
 
}
565
 
 
566
 
typedef struct {
567
 
  GOutputStream *stream;
568
 
  GAsyncReadyCallback callback;
569
 
  gpointer user_data;
570
 
} CloseAsyncData;
571
 
 
572
 
static gboolean
573
 
close_async_cb (CloseAsyncData *data)
574
 
{
575
 
  GUnixOutputStream *unix_stream;
576
 
  GSimpleAsyncResult *simple;
577
 
  GError *error = NULL;
578
 
  gboolean result;
579
 
  int res;
580
 
 
581
 
  unix_stream = G_UNIX_OUTPUT_STREAM (data->stream);
582
 
 
583
 
  if (!unix_stream->priv->close_fd)
584
 
    {
585
 
      result = TRUE;
586
 
      goto out;
587
 
    }
588
 
  
589
 
  while (1)
590
 
    {
591
 
      res = close (unix_stream->priv->fd);
592
 
      if (res == -1)
593
 
        {
594
 
          int errsv = errno;
595
 
 
596
 
          g_set_error (&error, G_IO_ERROR,
597
 
                       g_io_error_from_errno (errsv),
598
 
                       _("Error closing file descriptor: %s"),
599
 
                       g_strerror (errsv));
600
 
        }
601
 
      break;
602
 
    }
603
 
  
604
 
  result = res != -1;
605
 
  
606
 
 out:
607
 
  simple = g_simple_async_result_new (G_OBJECT (data->stream),
608
 
                                      data->callback,
609
 
                                      data->user_data,
610
 
                                      g_unix_output_stream_close_async);
611
 
 
612
 
  if (!result)
613
 
    g_simple_async_result_take_error (simple, error);
614
 
 
615
 
  /* Complete immediately, not in idle, since we're already in a mainloop callout */
616
 
  g_simple_async_result_complete (simple);
617
 
  g_object_unref (simple);
618
 
  
619
 
  return FALSE;
620
 
}
621
 
 
622
 
static void
623
 
g_unix_output_stream_close_async (GOutputStream        *stream,
624
 
                                  int                  io_priority,
625
 
                                  GCancellable        *cancellable,
626
 
                                  GAsyncReadyCallback  callback,
627
 
                                  gpointer             user_data)
628
 
{
629
 
  GSource *idle;
630
 
  CloseAsyncData *data;
631
 
 
632
 
  data = g_new0 (CloseAsyncData, 1);
633
 
 
634
 
  data->stream = stream;
635
 
  data->callback = callback;
636
 
  data->user_data = user_data;
637
 
  
638
 
  idle = g_idle_source_new ();
639
 
  g_source_set_callback (idle, (GSourceFunc)close_async_cb, data, g_free);
640
 
  g_source_attach (idle, g_main_context_get_thread_default ());
641
 
  g_source_unref (idle);
 
429
static void
 
430
g_unix_output_stream_close_async (GOutputStream       *stream,
 
431
                                  int                  io_priority,
 
432
                                  GCancellable        *cancellable,
 
433
                                  GAsyncReadyCallback  callback,
 
434
                                  gpointer             user_data)
 
435
{
 
436
  GTask *task;
 
437
  GError *error = NULL;
 
438
 
 
439
  task = g_task_new (stream, cancellable, callback, user_data);
 
440
  g_task_set_priority (task, io_priority);
 
441
 
 
442
  if (g_unix_output_stream_close (stream, cancellable, &error))
 
443
    g_task_return_boolean (task, TRUE);
 
444
  else
 
445
    g_task_return_error (task, error);
 
446
  g_object_unref (task);
642
447
}
643
448
 
644
449
static gboolean
646
451
                                   GAsyncResult   *result,
647
452
                                   GError        **error)
648
453
{
649
 
  /* Failures handled in generic close_finish code */
650
 
  return TRUE;
 
454
  g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
 
455
 
 
456
  return g_task_propagate_boolean (G_TASK (result), error);
 
457
}
 
458
 
 
459
static gboolean
 
460
g_unix_output_stream_pollable_can_poll (GPollableOutputStream *stream)
 
461
{
 
462
  return G_UNIX_OUTPUT_STREAM (stream)->priv->is_pipe_or_socket;
651
463
}
652
464
 
653
465
static gboolean
659
471
 
660
472
  poll_fd.fd = unix_stream->priv->fd;
661
473
  poll_fd.events = G_IO_OUT;
 
474
  poll_fd.revents = 0;
662
475
 
663
476
  do
664
477
    result = g_poll (&poll_fd, 1, 0);