apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "William A. Rowe, Jr." <wr...@apache.org>
Subject Re: Opaque types [was apr_mmap_t]
Date Mon, 25 Nov 2002 04:13:40 GMT
At 09:24 PM 11/24/2002, rbb@apache.org wrote:

>> I'm not arguing that exposing incomplete types wouldn't speed up APR.
>> In fact, well written accessors that are inline'able on all modern compilers
>> would be a beautiful thing.  They would work only for 'private' copies of
>> the apr library, since the app becomes permanently bound to the explicit
>> version installed at the time you build it.  That would be fine by httpd and
>
>There are very few compilers that can inline functions that are in
>separate libraries.  In fact, I don't currently know of any.

Of course, there are none that inline functions in libraries.  inline functions
need to exist in headers.  We might end up with a scenario such as...

apr_mmap.h  [public header]
  #include "apr.h"

  /* Incomplete type */
  typedef struct apr_mmap_t apr_mmap_t;

  /* Prototype */
  APR_DECLARE_INLINE(footype) apr_mmap_foo_get(apr_mmap_t *mmap);

  #if APR_HAS_INLINE && APR_USE_INLINE
  # include "apr_mmap_inline.h"
  #endif

apr_mmap_inline.h 
  /* This private header is included for inline declarations.
   * use of the embedded structures binds your application
   * to this specific build of APR.  These structures are subject
   * to change without warning. */

  struct apr_mmap_t {
    footype foo; ...
  } apr_mmap_t;

  /* Implementation */
  APR_DECLARE_INLINE(typefoo) apr_mmap_foo_get(apr_mmap_t *mmap) {
    
  }

mmap_inline.c
  #undef APR_USE_INLINE
  #include "apr_mmap.h"

  /* capture inline functions as exported real functions */
  #include "apr_mmap_inline.h"

mmap.c
  #define APR_USE_INLINE  /* if it's not simply global */
  #include "apr_mmap.h"

  APR_DECLARE(apr_status_t) apr_mmap_create(...) {
    ...
  }

Obviously, this is skeletal.  It provides that all functions are exported,
and some simple functions may be inlined.

>> other consumers who don't mind building APR themselves, or for apps
>> that are built via one of the packaging tools that tracks dependencies,
>> and will rebuild the entire slew of dependent packages when a new
>> version of APR is installed.
>>
>> Of course, this won't work for deployment across different platforms.
>
>I can't understand this statement at all.  Deployment across different
>platforms doesn't make sense in APR.

Sorry, wrong phrase.  Different target machines.  Think binary builds of
packages, where the package doesn't distribute APR, but presumes it
will be installed on the machine.  Binary compatibility to the inlines would
never fly, so that package builds without APR_USE_INLINE, for example.
Anyone building the package to include the specific release of APR would 
use inline, of course.

>> By committing to unwrapping all of the opaque types, you seem hell
>> bent on ensuring we forever break binary compatibility.  Opaque types
>
>Again, what in the world are you talking about?  The design that I
>suggested actually makes binary compatibility one of it's core goals.  I
>am a VERY strong believer in binary compat for libraries, so this
>statement makes little to no sense.  If you look at the design, you will
>see that it splits the structure into two parts:  1)  The logical
>component and 2)  The OS specific component.  Because there is an
>incomplete type in the middle of the structure, an allocator is still
>required to actually create an instance of a type.  That means that binary
>compat is easy to get, assuming all new fields are added at the end of the
>structure.  The only time you will get into trouble is if somebody passes
>the structure itself instead of a pointer to the structure.  Yes, binary
>compat would be broken between 1.0 and 2.0, but we never said that was a
>goal.

I don't believe what you suggest is portable.  Of course my VC is very happy
to parse a struct def with a pointer to an incomplete type anywhere within
the structure, or an undefined array at the *end* of the structure.  But since
we can't partially define a single structure, we will end up with either a pointer
and two allocs, or some cruft to perform a single allocation and stash a pointer
or 'presume' that the opaque component follows the transparent structure.
Either way, you still end up with a legitimate sizeof() unless the structure
allows some incomplete component at the end of the declaration.  Some
compilers don't. 

>> are goodness for versioning, portability, and extensions of the APR
>> library to other languages (e.g. tcl, perl, java etc, especially those
>> with OO schemas).  We (you especially) did a passable job of making
>> APR map very well to OO schemas.  Please consider their benefits
>> of opaque types before we make plans to wipe them out.
>
>Pay very close attention please.  Using a combination of complete and
>incomplete types allows for all of the advantages of both, with very few
>disadvantages.

Yes, but as I just stated in the last paragraph, I don't believe it's available
to all compilers.

>The idea of wrapping APR in an OO language has never been called out as a
>goal, but even if it is made into a goal, splitting the types into a
>combination of complete and incomplete will not hurt that goal at all.

No, it would not if that facility were portable :-)

Let me close by offering that we *better* not find out you are responding
to list messages while waiting in the delivery room/suite :-)  We can pick
up the dialog after you get back.  God bless the three of you :-)  

Bill


Mime
View raw message