gegl r2258 - in trunk: . gegl/buffer



Author: ok
Date: Mon Apr 28 22:01:17 2008
New Revision: 2258
URL: http://svn.gnome.org/viewvc/gegl?rev=2258&view=rev

Log:
Made on disk-buffers opened on disk perform locking when invoking
gegl_buffer_set, this allows transparent use of the buffers for writes
since only one write will happen at a time. (At the moment the lock
is implemented in the files header, and a GeglBuffer might get stuck
in a locked state on disk if gegl is aborted when it holds the lock.)
* gegl/buffer/gegl-buffer-access.c: (gegl_buffer_set): lock buffer
on write if the buffer is shared.
* gegl/buffer/gegl-buffer-index.h: fixed flags for header.
* gegl/buffer/gegl-buffer-private.h:
* gegl/buffer/gegl-buffer.c:
(gegl_buffer_is_shared): new function reports if the buffer is shared
(gegl_buffer_try_lock): tries to lock a shared buffer, if failed try
again a bit later.
(gegl_buffer_unlock): unlock a locked buffer, allows other clients to
use the buffer.
* gegl/buffer/gegl-tile-backend-file.[ch]: added _try_lock() _unlock()
* gegl/buffer/gegl-tile-backend.[ch]: added shared flag to backend.


Modified:
   trunk/ChangeLog
   trunk/gegl/buffer/gegl-buffer-access.c
   trunk/gegl/buffer/gegl-buffer-index.h
   trunk/gegl/buffer/gegl-buffer-private.h
   trunk/gegl/buffer/gegl-buffer.c
   trunk/gegl/buffer/gegl-tile-backend-file.c
   trunk/gegl/buffer/gegl-tile-backend-file.h
   trunk/gegl/buffer/gegl-tile-backend.c
   trunk/gegl/buffer/gegl-tile-backend.h

Modified: trunk/gegl/buffer/gegl-buffer-access.c
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-access.c	(original)
+++ trunk/gegl/buffer/gegl-buffer-access.c	Mon Apr 28 22:01:17 2008
@@ -579,6 +579,14 @@
 #if ENABLE_MP
   g_static_rec_mutex_lock (&mutex);
 #endif
+  if (gegl_buffer_is_shared(buffer))
+    {
+      while (gegl_buffer_try_lock (buffer)==FALSE)
+        {
+          g_print ("failed to aquire lock sleeping 1s");
+          g_usleep (1000000);
+        }
+    }
 
   if (format == NULL)
     format = buffer->format;
@@ -602,6 +610,11 @@
       g_object_unref (sub_buf);
     }
 
+  if (gegl_buffer_is_shared(buffer))
+    {
+      gegl_buffer_flush (buffer);
+      gegl_buffer_unlock (buffer);
+    }
 #if ENABLE_MP
   g_static_rec_mutex_unlock (&mutex);
 #endif

Modified: trunk/gegl/buffer/gegl-buffer-index.h
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-index.h	(original)
+++ trunk/gegl/buffer/gegl-buffer-index.h	Mon Apr 28 22:01:17 2008
@@ -9,7 +9,7 @@
 
 
 /* Increase this number when the structures change.*/
-#define GEGL_FILE_SPEC_REV     23
+#define GEGL_FILE_SPEC_REV     0
 #define GEGL_MAGIC             {'G','E','G','L'}
 
 #define GEGL_FLAG_TILE         1
@@ -21,9 +21,9 @@
 /* these flags are used for the header, the lower bits of the
  * header store the revision
  */
-#define GEGL_FLAG_LOCKED       (0xff*(1<<0))
-#define GEGL_FLAG_FLUSHED      (0xff*(1<<1))
-#define GEGL_FLAG_IS_HEADER    (0xff*(1<<3))
+#define GEGL_FLAG_LOCKED       (1<<(8+0))
+#define GEGL_FLAG_FLUSHED      (1<<(8+1))
+#define GEGL_FLAG_IS_HEADER    (1<<(8+3))
 
 /* The default header we expect to see on a file is that it is
  * flushed, and has the revision the file conforms to written

Modified: trunk/gegl/buffer/gegl-buffer-private.h
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-private.h	(original)
+++ trunk/gegl/buffer/gegl-buffer-private.h	Mon Apr 28 22:01:17 2008
@@ -91,4 +91,9 @@
 
 GeglTileBackend    * gegl_buffer_backend     (GeglBuffer *buffer);
 
+gboolean             gegl_buffer_is_shared   (GeglBuffer *buffer);
+
+gboolean             gegl_buffer_try_lock    (GeglBuffer *buffer);
+gboolean             gegl_buffer_unlock      (GeglBuffer *buffer);
+
 #endif

Modified: trunk/gegl/buffer/gegl-buffer.c
==============================================================================
--- trunk/gegl/buffer/gegl-buffer.c	(original)
+++ trunk/gegl/buffer/gegl-buffer.c	Mon Apr 28 22:01:17 2008
@@ -1009,3 +1009,24 @@
       }
   }
 }
+
+gboolean gegl_buffer_is_shared (GeglBuffer *buffer)
+{
+  GeglTileBackend *backend = gegl_buffer_backend (buffer);
+  return backend->shared;
+}
+
+gboolean gegl_buffer_try_lock (GeglBuffer *buffer)
+{
+  GeglTileBackend *backend = gegl_buffer_backend (buffer);
+  if (!backend->shared)
+    return FALSE;
+  return gegl_tile_backend_file_try_lock (GEGL_TILE_BACKEND_FILE (backend));
+}
+gboolean gegl_buffer_unlock (GeglBuffer *buffer)
+{
+  GeglTileBackend *backend = gegl_buffer_backend (buffer);
+  if (!backend->shared)
+    return FALSE;
+  return gegl_tile_backend_file_unlock (GEGL_TILE_BACKEND_FILE (backend));
+}

Modified: trunk/gegl/buffer/gegl-tile-backend-file.c
==============================================================================
--- trunk/gegl/buffer/gegl-tile-backend-file.c	(original)
+++ trunk/gegl/buffer/gegl-tile-backend-file.c	Mon Apr 28 22:01:17 2008
@@ -681,7 +681,7 @@
   GeglBufferHeader new_header;
   GList           *iter;
   GeglTileBackend *backend;
-  goffset offset;
+  goffset offset = 0;
   goffset max=0;
 
 /* compute total from and next pre alloc by monitoring tiles as they
@@ -689,6 +689,13 @@
  */
   /* reload header */
   new_header = gegl_buffer_read_header (self->i, &offset)->header;
+
+  while (new_header.flags & GEGL_FLAG_LOCKED)
+    {
+      g_usleep (500000);
+      new_header = gegl_buffer_read_header (self->i, &offset)->header;
+    }
+
   if (new_header.rev == self->header.rev)
     {
       GEGL_NOTE(TILE_BACKEND, "header not changed: %s", self->path);
@@ -827,6 +834,9 @@
       self->exist = TRUE;
       g_assert (self->i);
       g_assert (self->o);
+
+      /* to autoflush gegl_buffer_set */
+      backend->shared = TRUE;
     }
   else
     {
@@ -928,3 +938,31 @@
   self->next_pre_alloc = 256;  /* reserved space for header */
   self->total          = 256;  /* reserved space for header */
 }
+
+gboolean
+gegl_tile_backend_file_try_lock (GeglTileBackendFile *self)
+{
+  GeglBufferHeader new_header;
+  new_header = gegl_buffer_read_header (self->i, NULL)->header;
+  if (new_header.flags & GEGL_FLAG_LOCKED)
+    {
+      return FALSE;
+    }
+  self->header.flags += GEGL_FLAG_LOCKED;
+  write_header (self);
+  g_output_stream_flush (self->o, NULL, NULL);
+  return TRUE;
+}
+
+gboolean gegl_tile_backend_file_unlock (GeglTileBackendFile *self)
+{
+  if (!(self->header.flags & GEGL_FLAG_LOCKED))
+    {
+      g_warning ("tried to unlock unlocked buffer");
+      return FALSE;
+    }
+  self->header.flags -= GEGL_FLAG_LOCKED;
+  write_header (self);
+  g_output_stream_flush (self->o, NULL, NULL);
+  return TRUE;
+}

Modified: trunk/gegl/buffer/gegl-tile-backend-file.h
==============================================================================
--- trunk/gegl/buffer/gegl-tile-backend-file.h	(original)
+++ trunk/gegl/buffer/gegl-tile-backend-file.h	Mon Apr 28 22:01:17 2008
@@ -44,6 +44,9 @@
 
 void  gegl_tile_backend_file_stats    (void);
 
+gboolean gegl_tile_backend_file_try_lock (GeglTileBackendFile *file);
+gboolean gegl_tile_backend_file_unlock   (GeglTileBackendFile *file);
+
 G_END_DECLS
 
 #endif

Modified: trunk/gegl/buffer/gegl-tile-backend.c
==============================================================================
--- trunk/gegl/buffer/gegl-tile-backend.c	(original)
+++ trunk/gegl/buffer/gegl-tile-backend.c	Mon Apr 28 22:01:17 2008
@@ -159,4 +159,5 @@
 static void
 gegl_tile_backend_init (GeglTileBackend *self)
 {
+  self->shared = FALSE;
 }

Modified: trunk/gegl/buffer/gegl-tile-backend.h
==============================================================================
--- trunk/gegl/buffer/gegl-tile-backend.h	(original)
+++ trunk/gegl/buffer/gegl-tile-backend.h	Mon Apr 28 22:01:17 2008
@@ -43,6 +43,7 @@
   /* private */
   gpointer        header;
   gpointer        storage;
+  gboolean        shared;
 };
 
 struct _GeglTileBackendClass



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