1. 06 7月, 2016 1 次提交
  2. 12 5月, 2016 3 次提交
    • E
      qapi: Simplify semantics of visit_next_list() · d9f62dde
      Eric Blake 提交于
      The semantics of the list visit are somewhat baroque, with the
      following pseudocode when FooList is used:
      
      start()
      for (prev = head; cur = next(prev); prev = &cur) {
          visit(&cur->value)
      }
      
      Note that these semantics (advance before visit) requires that
      the first call to next() return the list head, while all other
      calls return the next element of the list; that is, every visitor
      implementation is required to track extra state to decide whether
      to return the input as-is, or to advance.  It also requires an
      argument of 'GenericList **' to next(), solely because the first
      iteration might need to modify the caller's GenericList head, so
      that all other calls have to do a layer of dereferencing.
      
      Thankfully, we only have two uses of list visits in the entire
      code base: one in spapr_drc (which completely avoids
      visit_next_list(), feeding in integers from a different source
      than uint8List), and one in qapi-visit.py.  That is, all other
      list visitors are generated in qapi-visit.c, and share the same
      paradigm based on a qapi FooList type, so we can refactor how
      lists are laid out with minimal churn among clients.
      
      We can greatly simplify things by hoisting the special case
      into the start() routine, and flipping the order in the loop
      to visit before advance:
      
      start(head)
      for (tail = *head; tail; tail = next(tail)) {
          visit(&tail->value)
      }
      
      With the simpler semantics, visitors have less state to track,
      the argument to next() is reduced to 'GenericList *', and it
      also becomes obvious whether an input visitor is allocating a
      FooList during visit_start_list() (rather than the old way of
      not knowing if an allocation happened until the first
      visit_next_list()).  As a minor drawback, we now allocate in
      two functions instead of one, and have to pass the size to
      both functions (unless we were to tweak the input visitors to
      cache the size to start_list for reuse during next_list, but
      that defeats the goal of less visitor state).
      
      The signature of visit_start_list() is chosen to match
      visit_start_struct(), with the new parameters after 'name'.
      
      The spapr_drc case is a virtual visit, done by passing NULL for
      list, similarly to how NULL is passed to visit_start_struct()
      when a qapi type is not used in those visits.  It was easy to
      provide these semantics for qmp-output and dealloc visitors,
      and a bit harder for qmp-input (several prerequisite patches
      refactored things to make this patch straightforward).  But it
      turned out that the string and opts visitors munge enough other
      state during visit_next_list() to make it easier to just
      document and require a GenericList visit for now; an assertion
      will remind us to adjust things if we need the semantics in the
      future.
      
      Several pre-requisite cleanup patches made the reshuffling of
      the various visitors easier; particularly the qmp input visitor.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Message-Id: <1461879932-9020-24-git-send-email-eblake@redhat.com>
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      d9f62dde
    • E
      qapi: Add visit_type_null() visitor · 3bc97fd5
      Eric Blake 提交于
      Right now, qmp-output-visitor happens to produce a QNull result
      if nothing is actually visited between the creation of the visitor
      and the request for the resulting QObject.  A stronger protocol
      would require that a QMP output visit MUST visit something.  But
      to still be able to produce a JSON 'null' output, we need a new
      visitor function that states our intentions.  Yes, we could say
      that such a visit must go through visit_type_any(), but that
      feels clunky.
      
      So this patch introduces the new visit_type_null() interface and
      its no-op interface in the dealloc visitor, and stubs in the
      qmp visitors (the next patch will finish the implementation).
      For the visitors that will not implement the callback, document
      the situation. The code in qapi-visit-core unconditionally
      dereferences the callback pointer, so that a segfault will inform
      a developer if they need to implement the callback for their
      choice of visitor.
      
      Note that JSON has a primitive null type, with the single value
      null; likewise with the QNull type for QObject; but for QAPI,
      we just have the 'null' value without a null type.  We may
      eventually want to add more support in QAPI for null (most likely,
      we'd use it via an alternate type that permits 'null' or an
      object); but we'll create that usage when we need it.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Message-Id: <1461879932-9020-15-git-send-email-eblake@redhat.com>
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      3bc97fd5
    • E
      qapi: Document visitor interfaces, add assertions · adfb264c
      Eric Blake 提交于
      The visitor interface for mapping between QObject/QemuOpts/string
      and QAPI is scandalously under-documented, making changes to visitor
      core, individual visitors, and users of visitors difficult to
      coordinate.  Among other questions: when is it safe to pass NULL,
      vs. when a string must be provided; which visitors implement which
      callbacks; the difference between concrete and virtual visits.
      
      Correct this by retrofitting proper contracts, and document where some
      of the interface warts remain (for example, we may want to modify
      visit_end_* to require the same 'obj' as the visit_start counterpart,
      so the dealloc visitor can be simplified).  Later patches in this
      series will tackle some, but not all, of these warts.
      
      Add assertions to (partially) enforce the contract.  Some of these
      were only made possible by recent cleanup commits.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      Message-Id: <1461879932-9020-13-git-send-email-eblake@redhat.com>
      [Doc fix from Eric squashed in]
      Signed-off-by: NMarkus Armbruster <armbru@redhat.com>
      adfb264c
  3. 19 12月, 2012 1 次提交
  4. 21 2月, 2012 1 次提交