On Wed, 2006-09-20 at 12:31 +0200, Alexander Larsson wrote:

> Here is my current GInputStream:

very nice. Comments below.

> 
> struct _GInputStreamClass
> {
>   GObjectClass parent_class;
> 
>   /* Sync ops: */
>   

Do you dislike the idea of moving the GError as a member of the
GInputStream instance ?

>   gssize   (* read)        (GInputStream *stream,
>                           void         *buffer,
>                           gsize         count,
>                           GError      **error);
>   gssize   (* skip)        (GInputStream *stream,
>                           gsize         count,
>                           GError      **error);
>   gboolean (* close)     (GInputStream *stream,
>                           GError      **error);
> 

1) Don't you think it might make sense to also add an io priority arg to
the sync functions ?
2) What is the signature of GDestroyNotify ?
3) Do you expect GDestroyNotify to be invoked afer GAsyncReadCallback
during normal successful reads ?

>   /* Async ops: (optional in derived classes) */
>   guint    (* read_async)  (GInputStream  *stream,
>                           void               *buffer,
>                           gsize               count,
>                           int                 io_priority,
>                           GMainContext       *context,
>                           GAsyncReadCallback  callback,
>                           gpointer            data,
>                           GDestroyNotify      notify);
>   guint    (* close_async) (GInputStream  *stream,
>                           GMainContext       *context,
>                           GAsyncCloseCallback callback,
>                           gpointer            data,
>                           GDestroyNotify      notify);
>   void     (* cancel)      (GInputStream  *stream,
>                           guint               tag);
> }
> 
> GInputStream objects can optionally also implement the GSeekable
> interface to support seeking and truncating. This is your basic
> syncronous read API with an addition of some async calls. If a derived
> class doesn't implement the async calls the baseclass will emulate them
> using threads (similar to how gnome-vfs works now). GOutputStream is
> similar, without the skip method, but with a flush method added.
> 
> These are then used in the vfs to handle document reading. The API for
> reading a file is simple, it would be something like:
> GInputStream *g_file_read(GFile *file);
> 
> For writing a file things are a bit more complex. An example API set
> could be:
> GOutputStream *g_file_append_to (GFile *file);
> GOutputStream *g_file_create    (GFile *file);
> GOutputStream *g_file_replace   (GFile *file,
>                                time_t mtime_of_old_version, /* optional */
>                                char *backup_name /* optional */ );
> 
> Error handling on open is handled by the stream (to avoid forcing a sync
> open). The replace operation does the optimal handling of atomic replace
> and backup for the specific backend.

Are you saying that _append and _create would not be synchronous
operations ? If so, what happens if I attempt a sync read after an async
_append and the async _append fails ? Will the sync read fail and report
the error of the async _append ? Is there a way to schedule an open
barrier ? that is, be notified upon open completion with the operation
status ?

Mathieu
-- 

_______________________________________________
gnome-vfs-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gnome-vfs-list

Reply via email to