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

Re: [Xen-devel] [PATCH 2/3] RFC: libxl: API changes re event handling



Ian Campbell writes ("Re: [Xen-devel] [PATCH 2/3] RFC: libxl: API changes re 
event handling"):
> I think it would be good to have the model validated by Jim (CC'd) since
> I imagine that the libvirt backend will be one of the primary users of
> the registration mechanism.

Indeed.  I was thinking about libvirt (and I think I remember how the
libvirt fd and event handling works from when I read it last time)
amongst other callers.

> There's a lot of docs here, which is excellent, but I've only had two
> cups of tea so far today so I only managed a fairly high-level think
> about it all.

:-).

Thanks for all your comments.  Detailed reponsese follow:

> > + * The second approach uses libxl_osevent_register_hooks and is
> > + * suitable for programs which are already using a callback-based
> > + * event library.
> 
> An example of this style of usage would be handy too.

It's not going to be very interesting.  You basically just implement
the fd_register etc. in terms of your own event system.

> > +int libxl_osevent_beforepoll(libxl_ctx *ctx, int *nfds_io,
> > +                           struct poll *fds, int *timeout_upd);
> > +  /* app should provide beforepoll with some fds, and give number in 
> > *nfds_io.
> > +   * *nfds_io will in any case be updated according to how many we want.
> > +   * if space was sufficient, fills in fds[0..<new *nfds_io>]
> > +   *   and updates *timeout_upd if needed and returns ok.
> > +   * if space was insufficient, fds[0..<old *nfds_io>] is undefined,
> > +   *  *timeout_upd may or may not have been updated, returns 
> > ERROR_BUFERFULL.
> > +   */
> 
> It's not immediately obvious but I presume the user is entitled to
> provide an fds etc which already contains the file descriptors it is
> itself interested in and that this function will augment it.

No; the user is supposed to pass libxl a pointer to a subsection of
the array which is for libxl's use.

> Is there some way for a caller to determine how many entries in the
> struct poll * the library will use?

Yes.  Call it with fds==NULL and *nfds_io==0.  Is this not clear ?

> Should we also have an interface suitable for users of select?

Possibly.  Most people are using poll nowadays though.  I would wait
with providing it until someone wants it, at which point it's a SMOP.

> It is currently conventional in libxl.h to document a function before
> it's prototype rather than after.

I think this is unhelpful.  Can we change this convention ?

> > +void libxl_osevent_afterpoll(libxl_ctx *ctx, int nfds, const struct poll 
> > *fds);
> > +  /* nfds and fds[0..nfds] must be from _beforepoll as modified by poll
> > +   */
> 
> What does this function do in practice?

All things that libxl wants to do and which can be done according to
fds[].revents (and the time).  I should add something about this to
the comment, evidently.

If you don't call this then libxl_event_check may claim there are no
events to be had because libxl hasn't read the relevant fds.

> > +int libxl_osevent_register_hooks(libxl_ctx *ctx, void *user,
> > +  int (*fd_register)(void *user, int fd, void **for_app_registration_out,
> > +                     short events, void *for_libxl),
> > [...]
> > +  void (*time_deregister)(void *user, void *for_app_registration_io,
> > +                          void *for_libxl));
> 
> I think passing a pointer to a struct libxl_osevent_hooks would be
> better than passing loads of fn pointers.

You're right.

> > +  /* The application which calls register_fd_hooks promises to
> > +   * maintain a register of fds and timeouts that libxl is interested
> > +   * in,
> 
> It would probably be useful to provide some helper functions for
> maintaining this register and for dispatching the foo_occurred things.

Applications that want to use this interface already have one of
those.  Ie, any application with an existing callback-style event
loop.  They already have the appropriate data structures.

> [...]
> >  typedef struct {
> >      /* event type */
> > @@ -293,41 +410,136 @@ typedef struct {
> >      char *token;
> >  } libxl_event;

This struct libxl_event leaked through; it's to be abolished in favour
of the one from the idl.

> > +int libxl_event_check(libxl_ctx *ctx, libxl_event *event_r,
> > +                      unsigned long typemask,
> > +                      int (*predicate)(const libxl_event*, void *user),
> > +                      void *predicate_user);
> 
> I was a little confused for a while because this function is associated
> with the libxl_osevent_*poll methods but the register_hooks stuff is
> defined in the middle. I think it would be better to define both sets of
> functions in contiguous and distinct blocks.

No, libxl_event_check can be used with either
osevent_before/afterpoll, or osevent_register_hooks.  You can mix and
match.

libxl_osevent_* are interchangeable (and miscible) ways of getting
fd readability, timeouts, etc., into libxl.

libxl_event_8 are interchangeable (and miscible) ways of getting
higher-level occurrences about domains out of libxl and into the
application.

> > +int libxl_event_wait(libxl_ctx *ctx, libxl_event *event_r,
> > +                     unsigned long typemask,
> > +                     int (*predicate)(const libxl_event*, void *user),
> > +                     void *predicate_user);
> > +  /* Like libxl_event_check but blocks if no suitable events are
> > +   * available, until some are.  Uses
> > +   * libxl_osevent_beforepoll/_afterpoll so may be inefficient if very
> > +   * many domains are being handled by a single program.
> > +   */
> [...]
> > +int libxl_event_free(libxl_ctx, *ctx, libxl_event *event);
> 
> It looks as if the libxl_event passed to libxl_event_wait is owned by
> the caller so it could use a local struct or manage allocation itself,
> is that right?

No, there's one too few *s.  It should be
  int libxl_event_wait(libxl_ctx *ctx, libxl_event **event_out,

> > +/* Alternatively or additionally, the application may also use this: */
> > +
> > +void libxl_event_register_callbacks(libxl_ctx *ctx, void *user, uint64_t 
> > mask,
> > +   void (*event_occurs)(void *user, const libxl_event *event),
> > +   void (*disaster)(void *user, libxl_event_type type,
> > +                    const char *msg, int errnoval));
> > +  /*
> > +   * Arranges that libxl will henceforth call event_occurs for any
> > +   * events whose type is set in mask, rather than queueing the event
> > +   * for retrieval by libxl_event_check/wait.  Events whose bit is
> > +   * clear in mask are not affected.
> 
> Would it be useful to have separate callbacks for the different event
> types?

I don't think so.

> Or perhaps just a helper function which can be registered here and takes
> a dispatch table from the app (I suppose the app could build this
> itself, but maybe it would be useful functionality).

The application might want to select by domain first, and then by
type.  I don't think it would be right to force it into a particular
structure.  It's not like a dispatch table is hard to do in the
application if you want to - it's just an array, which you can index
directly with the type number.

> > +typedef struct libxl_awaiting_disk_eject libxl_awaiting_disk_eject;
> 
> Is this struct defined in the IDL? If yes then I think you get this for
> free. If no then shouldn't it be?

No, it's an opaque thing used by the library to store its own
information about the application's interest.

> > +libxl_event = Struct("event",[
> > +    ("domid",    libxl_domid),
> > +    ("domuuid",  libxl_uuid),
> > +    ("type",     libxl_event_type),
> > +    ("for_user", uint64),
> > +    ("u", KeyedUnion(None,"type",
> > +          [("domain_shutdown", Struct(None, [
> > +                                             ("shutdown_reason", uint8)
> > +                                      ])),
> > +           ("domain_destroy", Struct()),
> > +           ("disk_eject", Struct(None, [
> > +                                        ("vdev", string)
> > +                                        ("disk", libxl_device_disk)
> > +                                 ])),
> > +           ]))])
> 
> It might be convenient to users if these structs were named so they can
> dispatch to handle_domain_shutdown(struct libxl_event_domain_shutdown
> *info) ?

I'm not sure I follow.

Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.