[Spice-devel] [PATCH 4/4] add some comments to cursor-channel.h header
Jonathon Jongsma
jjongsma at redhat.com
Thu May 26 17:24:09 UTC 2016
On Thu, 2016-05-26 at 06:59 -0400, Frediano Ziglio wrote:
> >
> > On Fri, 2016-05-13 at 10:16 +0100, Frediano Ziglio wrote:
> > > Explain usage of the class.
> > >
> > > Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
> > > ---
> > > server/cursor-channel.h | 30 +++++++++++++++++++++++++++++-
> > > 1 file changed, 29 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/server/cursor-channel.h b/server/cursor-channel.h
> > > index 6c89bc3..7e801a4 100644
> > > --- a/server/cursor-channel.h
> > > +++ b/server/cursor-channel.h
> > > @@ -23,20 +23,48 @@
> > > #include "red-worker.h"
> > > #include "red-parse-qxl.h"
> > >
> > > +/**
> > > + * This type it's a RedChannel class which implement cursor (mouse)
> >
> > it's -> is
> > implement -> implements
> >
> > > + * movements.
> > > + * A pointer to CursorChannel can be converted to a RedChannel.
> > > + */
> > > typedef struct CursorChannel CursorChannel;
> > >
> > > +/**
> > > + * Create CursorChannel.
> > > + * CursorChannel is intended to be run in a separate thread so
> > > + * so users of this class should attempt to serialize the class
> > > + * execution and setup client callbacks after creating the class
> > > + * using cursor_channel_client_migrate and cursor_channel_connect
> > > + * as helpers.
> > > + */
> >
> > I'm afraid I don't fully understand what this comment is trying to
> > communicate.
> >
>
> It's hard to explain in my natural language more in English.
>
> A RedChannel is mainly executed in a single thread, with the exception
> of the client callbacks, as described in red-channel.h:
>
> /*
> * callbacks that are triggered from client events.
> * They should be called from the thread that handles the RedClient
> */
> typedef struct {
> channel_client_connect_proc connect;
> channel_client_disconnect_proc disconnect;
> channel_client_migrate_proc migrate;
> } ClientCbs;
>
> mostly channels execute in the main thread (like MainChannel, InputsChannels)
> which is the same RedClient is executed however CursorChannel and
> DisplayChannel are executed in the worker thread (RedWorker).
> Now, if a RedChannel code has to be executed in a single thread and if
> RedClient is calling these callbacks from its thread (which in case of
> CursorChannel and DisplayChannel is different) how are handled these
> functions?
> Basically for CursorChannel and DisplayChannel these callbacks are
> provided by RedQXL (see red_qxl_init in red-qxl.c). These callbacks
> dispatch the request using the dispatcher to RedWorker (see for
> instance red_qxl_cursor_migrate) where an handler (like
> handle_dev_cursor_migrate) calls the correct CursorChannel/DisplayChannel
> callback (like cursor_channel_client_migrate).
> Basically RedQXL work as a wrapper to these function serializing their
> execution.
> Citing design pattern this would be better to be designed as a Decorator
> pattern adding serialization to CursorChannel/DisplayChannel instead
> of exposing the functions as normal functions and having to replace
> the callbacks. This would require having a proper interface for
> client callbacks and as a good consequence RedClient would be forced
> to use the safe (threading speaking) interface instead of possibly
> being able to call any RedChannel functions.
> Also this would avoid to expose these callback in the headers.
>
> Hope that this description helps to get some better comment describing
> the reason of these functions. Any suggestion for the comment are
> welcome.
OK. I had to read this over quite a few times, but I think I understand the
point now. And it means that my comment on the previous patch is probably a bit
off-base. How about something like this (hopefully I understood things properly
and the following is actually true)?
----
Since CursorChannel is intended to be run in a separate thread, it does not
register its own client callbacks since they would be called from a different
thread. Therefore users of this class are responsible for registering their own
client callbacks for CursorChannel. These 'wrapper' client callbacks must
forward execution on to the CursorChannel thread.
cursor_channel_client_migrate() and cursor_channel_connect() are provided as
helper functions and should only be called from the CursorChannel thread.
----
Not sure whether that's more clear to others, but it seems a bit more clear to
me (assuming I've understood things properly).
>
> > > CursorChannel* cursor_channel_new (RedWorker *worker);
> > > -void cursor_channel_disconnect (CursorChannel
> > > *cursor_channel);
> > > +
> > > +/**
> > > + * Cause the channel to disconnect all clients
> > > + */
> > > +void cursor_channel_disconnect (CursorChannel *cursor);
> > > void cursor_channel_reset (CursorChannel *cursor);
> > > void cursor_channel_init (CursorChannel *cursor);
> > > void cursor_channel_process_cmd (CursorChannel *cursor,
> > > RedCursorCmd *cursor_cmd);
> > > void cursor_channel_set_mouse_mode(CursorChannel *cursor,
> > > uint32_t mode);
> > > +
> > > +/**
> > > + * Connect a new client to CursorChannel.
> > > + * This is the equivalent of ReChannel client connect callback.
Add short comment about how it can only be called from cursor channel thread?
> > > + * See comment on cursor_channel_new.
> > > + */
> > > void cursor_channel_connect (CursorChannel *cursor,
> > > RedClient *client,
> > > RedsStream *stream,
> > > int migrate,
> > > uint32_t *common_caps,
> > > int
> > > num_common_caps,
> > > uint32_t *caps, int
> > > num_caps);
> > >
> > > +/**
> > > + * Migrate a client channel from a CursorChannel.
> > > + * This is the equivalent of ReChannel client migrate callback.
same?
> > > + * See comment on cursor_channel_new.
> > > + */
> > > void cursor_channel_client_migrate(RedChannelClient
> > > *client);
> > >
> > > #endif /* CURSOR_CHANNEL_H_ */
> >
> >
> > Otherwise looks fine.
> >
> > Reviewed-by: Jonathon Jongsma <jjongsma at redhat.com>
> >
>
> Frediano
More information about the Spice-devel
mailing list