[libgit2-glib] ggit-blob-output-stream: port to the new stream api



commit 0c55acb69d159ff7731f021ab756693271d6260b
Author: Ignacio Casal Quinteiro <icq gnome org>
Date:   Fri Feb 3 23:54:38 2017 +0100

    ggit-blob-output-stream: port to the new stream api

 libgit2-glib/ggit-blob-output-stream.c |  254 +++++++++----------------------
 1 files changed, 74 insertions(+), 180 deletions(-)
---
diff --git a/libgit2-glib/ggit-blob-output-stream.c b/libgit2-glib/ggit-blob-output-stream.c
index cb7565c..9027ff8 100644
--- a/libgit2-glib/ggit-blob-output-stream.c
+++ b/libgit2-glib/ggit-blob-output-stream.c
@@ -26,20 +26,6 @@
 #include <git2.h>
 #include <string.h>
 
-/*
- * BLOB_CHUNKING_STATE_IDLE: stream's thread is waiting for data
- * BLOB_CHUNKING_STATE_SENDING: have data, outside thread is waiting for result
- * BLOB_CHUNKING_STATE_CANCELLED: cancelled, stream's thread to exit and set error result
- * BLOB_CHUNKING_STATE_CLOSED: closed by outside thread or error, exit and set result
- */
-typedef enum
-{
-       BLOB_CHUNKING_STATE_IDLE,
-       BLOB_CHUNKING_STATE_SENDING,
-       BLOB_CHUNKING_STATE_CANCELLED,
-       BLOB_CHUNKING_STATE_CLOSED
-} BlobChunkingState;
-
 /**
  * GgitBlobOutputStream:
  *
@@ -49,20 +35,12 @@ typedef enum
 typedef struct _GgitBlobOutputStreamPrivate
 {
        GgitRepository *repository;
-       GThread *thread;
 
-       GMutex mutex;
-       GCond cond;
-
-       gssize written;
-
-       const gchar *writebuf;
-       gsize bufsize;
+       git_writestream *stream;
+       gboolean something_written;
 
        gint ret;
        GgitOId *oid;
-
-       BlobChunkingState state;
 } GgitBlobOutputStreamPrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE (GgitBlobOutputStream, ggit_blob_output_stream, G_TYPE_OUTPUT_STREAM)
@@ -85,24 +63,39 @@ ggit_blob_output_stream_close (GOutputStream  *object,
 
        if (g_cancellable_set_error_if_cancelled (cancellable, error))
        {
-               g_mutex_lock (&priv->mutex);
+               return FALSE;
+       }
+
+       if (priv->ret != GIT_OK)
+       {
+               return TRUE;
+       }
+
+       if (priv->something_written)
+       {
+               git_oid oid;
 
-               if (priv->state != BLOB_CHUNKING_STATE_CANCELLED)
+               if (git_blob_create_fromstream_commit (&oid, priv->stream) == GIT_OK)
                {
-                       priv->state = BLOB_CHUNKING_STATE_CANCELLED;
-                       g_cond_signal (&priv->cond);
+                       priv->oid = _ggit_oid_wrap (&oid);
+               }
+               else
+               {
+                       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                                    "Could not create object id");
+                       return FALSE;
+               }
+       }
+       else
+       {
+               if (priv->stream->close (priv->stream) != GIT_OK)
+               {
+                       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                                    "Could not close write stream");
+                       return FALSE;
                }
-
-               g_mutex_unlock (&priv->mutex);
-               return FALSE;
        }
 
-       g_mutex_lock (&priv->mutex);
-       priv->state = BLOB_CHUNKING_STATE_CLOSED;
-       g_cond_signal (&priv->cond);
-       g_mutex_unlock (&priv->mutex);
-
-       g_thread_join (priv->thread);
        return TRUE;
 }
 
@@ -128,56 +121,43 @@ ggit_blob_output_stream_write (GOutputStream  *object,
 {
        GgitBlobOutputStream *stream = GGIT_BLOB_OUTPUT_STREAM (object);
        GgitBlobOutputStreamPrivate *priv;
-       gssize written;
 
        priv = ggit_blob_output_stream_get_instance_private (stream);
 
-       g_mutex_lock (&priv->mutex);
-
-       while (priv->state == BLOB_CHUNKING_STATE_SENDING)
+       if (g_cancellable_set_error_if_cancelled (cancellable, error))
        {
-               g_cond_wait (&priv->cond, &priv->mutex);
+               return -1;
        }
 
-       if (priv->state == BLOB_CHUNKING_STATE_CLOSED)
+       if (priv->ret != GIT_OK)
        {
-               g_mutex_unlock (&priv->mutex);
-               return 0;
+               g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                            "Could not create write stream");
+               return -1;
        }
 
-       if (g_cancellable_is_cancelled (cancellable))
+       if (count == 0)
        {
-               priv->state = BLOB_CHUNKING_STATE_CANCELLED;
+               return 0;
        }
 
-       if (priv->state == BLOB_CHUNKING_STATE_IDLE)
+       if (count > 0)
        {
-               priv->writebuf = buffer;
-               priv->bufsize = count;
-               priv->written = 0;
-               priv->state = BLOB_CHUNKING_STATE_SENDING;
-       }
-
-       g_cond_signal (&priv->cond);
+               gint ret = 0;
 
-       while (priv->state == BLOB_CHUNKING_STATE_SENDING)
-       {
-               g_cond_wait (&priv->cond, &priv->mutex);
-       }
+               ret = priv->stream->write (priv->stream, buffer, count);
 
-       if (priv->state == BLOB_CHUNKING_STATE_CANCELLED)
-       {
-               g_cancellable_set_error_if_cancelled (cancellable, error);
-               written = -1;
-       }
-       else
-       {
-               written = priv->written;
+               if (ret == GIT_OK)
+               {
+                       priv->something_written = TRUE;
+                       return count;
+               }
        }
 
-       g_mutex_unlock (&priv->mutex);
+       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                    "Could not write the blob");
 
-       return written;
+       return -1;
 }
 
 static void
@@ -189,13 +169,16 @@ ggit_blob_output_stream_finalize (GObject *object)
        stream = GGIT_BLOB_OUTPUT_STREAM (object);
        priv = ggit_blob_output_stream_get_instance_private (stream);
 
-       g_mutex_clear (&priv->mutex);
-       g_cond_clear (&priv->cond);
 
        if (priv->oid)
        {
                ggit_oid_free (priv->oid);
        }
+       else
+       {
+               /* NOTE: if we have an oid the stream is already freed */
+               priv->stream->free (priv->stream);
+       }
 
        g_clear_object (&priv->repository);
 
@@ -240,6 +223,22 @@ ggit_blob_output_stream_get_property (GObject    *object,
 }
 
 static void
+ggit_blob_output_stream_constructed (GObject *object)
+{
+       GgitBlobOutputStream *stream;
+       GgitBlobOutputStreamPrivate *priv;
+
+       stream = GGIT_BLOB_OUTPUT_STREAM (object);
+       priv = ggit_blob_output_stream_get_instance_private (stream);
+
+       priv->ret = git_blob_create_fromstream (&priv->stream,
+                                               _ggit_native_get (priv->repository),
+                                              NULL);
+
+       G_OBJECT_CLASS (ggit_blob_output_stream_parent_class)->constructed (object);
+}
+
+static void
 ggit_blob_output_stream_class_init (GgitBlobOutputStreamClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -248,6 +247,7 @@ ggit_blob_output_stream_class_init (GgitBlobOutputStreamClass *klass)
        object_class->finalize = ggit_blob_output_stream_finalize;
        object_class->get_property = ggit_blob_output_stream_get_property;
        object_class->set_property = ggit_blob_output_stream_set_property;
+       object_class->constructed = ggit_blob_output_stream_constructed;
 
        stream_class->write_fn = ggit_blob_output_stream_write;
        stream_class->close_fn = ggit_blob_output_stream_close;
@@ -264,123 +264,17 @@ ggit_blob_output_stream_class_init (GgitBlobOutputStreamClass *klass)
                                                              G_PARAM_STATIC_STRINGS));
 }
 
-static int
-blob_chunk_cb (char   *content,
-               size_t  maxlen,
-               void   *payload)
-{
-       GgitBlobOutputStream *stream = payload;
-       GgitBlobOutputStreamPrivate *priv;
-       int written = 0;
-
-       priv = ggit_blob_output_stream_get_instance_private (stream);
-
-       g_mutex_lock (&priv->mutex);
-
-       while (priv->state == BLOB_CHUNKING_STATE_IDLE)
-       {
-               g_cond_wait (&priv->cond, &priv->mutex);
-       }
-
-       if (priv->state == BLOB_CHUNKING_STATE_CLOSED)
-       {
-               g_mutex_unlock (&priv->mutex);
-               return 0;
-       }
-
-       if (priv->state == BLOB_CHUNKING_STATE_CANCELLED)
-       {
-               g_mutex_unlock (&priv->mutex);
-               return -1;
-       }
-
-       /* state must be BLOB_CHUNKING_STATE_SENDING */
-
-       if (priv->bufsize > maxlen)
-       {
-               priv->written = maxlen;
-       }
-       else
-       {
-               priv->written = priv->bufsize;
-       }
-
-       if (priv->written > 0)
-       {
-               memcpy (content, priv->writebuf, priv->written);
-               written = priv->written;
-       }
-
-       priv->state = BLOB_CHUNKING_STATE_IDLE;
-       g_cond_signal (&priv->cond);
-       g_mutex_unlock (&priv->mutex);
-
-       return written;
-}
-
-static gpointer
-chunk_blob_in_thread (gpointer data)
-{
-       GgitBlobOutputStream *stream = data;
-       GgitBlobOutputStreamPrivate *priv;
-       git_oid oid;
-       gint ret;
-
-       priv = ggit_blob_output_stream_get_instance_private (stream);
-
-       ret = git_blob_create_fromchunks (&oid,
-                                         _ggit_native_get (priv->repository),
-                                         NULL,
-                                         blob_chunk_cb,
-                                         data);
-
-       g_mutex_lock (&priv->mutex);
-       priv->ret = ret;
-
-       if (ret == GIT_OK)
-       {
-               priv->state = BLOB_CHUNKING_STATE_CLOSED;
-               priv->oid = _ggit_oid_wrap (&oid);
-       }
-       else
-       {
-               priv->state = BLOB_CHUNKING_STATE_CANCELLED;
-       }
-
-       g_cond_signal (&priv->cond);
-
-       g_mutex_unlock (&priv->mutex);
-
-       return NULL;
-}
-
 static void
 ggit_blob_output_stream_init (GgitBlobOutputStream *stream)
 {
-       GgitBlobOutputStreamPrivate *priv;
-
-       priv = ggit_blob_output_stream_get_instance_private (stream);
-
-       g_mutex_init (&priv->mutex);
-       g_cond_init (&priv->cond);
-
-       priv->state = BLOB_CHUNKING_STATE_IDLE;
-
-       priv->thread = g_thread_new ("ggit-blob-output-stream",
-                                    chunk_blob_in_thread,
-                                    stream);
 }
 
 GgitBlobOutputStream *
 _ggit_blob_output_stream_new (GgitRepository  *repository)
 {
-       GgitBlobOutputStream *s;
-
-       s = g_object_new (GGIT_TYPE_BLOB_OUTPUT_STREAM,
-                         "repository", repository,
-                         NULL);
-
-       return s;
+       return g_object_new (GGIT_TYPE_BLOB_OUTPUT_STREAM,
+                            "repository", repository,
+                            NULL);
 }
 
 /**


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]