serf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Bert Huijben" <>
Subject RE: [serf-dev] [serf] r2489 committed - In preparation of serf 1.4.0, remove the get_remaining function from t...
Date Thu, 08 Oct 2015 08:18:04 GMT
It can’t be that smart that it sees inside different binaries… It just knew all the exports
are the same. (There are compiler/linker flags to suppress this combine behavior).


We currently don’t export the ‘extern’ variables from the shared library on Windows,
so if we want to export them we have to change something… Currently they are just not exported.

(Note that the way Subversion exports its variables via the .def file was deprecated before
we even started the Subversion project. It should have used the more modern syntax in the
.def file that exports the variables in a slightly different way)


I don’t see how using the __declspec(dllimport) would break existing binaries. We want the
new pointers to match for new binaries, while not having matching pointers for old binaries
wouldn’t break anybody. I fully agree that it is not nice to have those declarations in
the code, but it is not that adding these now wouldn’t work.




From: Greg Stein [] 
Sent: woensdag 7 oktober 2015 23:48
To: Bert Huijben <>
Subject: Re: [serf-dev] [serf] r2489 committed - In preparation of serf 1.4.0, remove the
get_remaining function from t...


On Wed, Oct 7, 2015 at 9:46 AM, Bert Huijben < <>
> wrote:

> -----Original Message-----
> From: Greg Stein [ <> ]
> Sent: zaterdag 12 september 2015 14:09
> To: <> 
> Subject: Re: [serf-dev] [serf] r2489 committed - In preparation of serf 1.4.0,
> remove the get_remaining function from t...
> [redirected to dev@serf]
> On Mon, Apr 6, 2015 at 8:32 AM, Bert Huijben < <>
> wrote:

> So you're saying that a pointer to a specific function might have *two*
> values under Windows? Within a single executable? That A could see a
> different value from B?

Yes, see the other mail explaining the cases when you can see this.
(Proxy functions calling into shared libraries, etc.)




And I even found a case where two functions with different names but identical behavior returned
the same value. (When using link time code generation; part of full program optimization)


Heh. I wonder if it knows function pointer comparisons occur, and will avoid that optimization?


> Assuming that is the case (or we wouldn't be in this situation), then let's
> change how v2 is API-compatibly detected. Again, let's use read_bucket()
> since it gives us a lot of flexibility and nobody has ever used it. Let's
> define a "V2_API_BUCKET" type and then ask for bucket FOO to return one
> of
> those. If FOO's type has a NULL read_bucket pointer, or returns NULL for
> that bucket type, then it is V1. If FOO's type has been updated, then it
> *can* return a V2 bucket (which does nothing; could be a static const data
> struct).

Currently all the vtable implementations are static. How are we going to publish the 'type'
for this, to pass to the function as argument?


No, they're "extern const". See serf_bucket_types.h. That's how the SERF_BUCKET_IS_FOO() macros


Sharing data from shared libraries introduces new problems... perhaps using a helper function
to obtain the value to pass?


We've been sharing data from shared libraries since day one :-)


I don't think we want to have that implementation hidden in a macro any more if there is so
much processing inserted.


I wouldn't worry about the amount of code, but simply that it would be hard to express as
a macro. So I guess we could have a simple test function:


int serf_bucket_is_v2(const serf_bucket_t *bucket);


.. and use the logic I describe above.


> That will skip any function pointer comparisons. We *do* switch to a data
> value (serf_bucket_type_v2_api), but I'm guessing Windows *does* have a
> singular constant value for that within the program space.

This really depends on how you declare it. With the right .def and/or __declspec() magic this
can work, but it still feels like a hack.


We've been doing data pointer comparisons the whole time. Our code depends upon it.


Note: we cannot use the __declspec(dllimport) magic to unify function pointers. There are
binaries out there which have *not* been compiled that way. We'd break binary compatibility
if we switched to demand that declaration form.


Can't we just extend serf_bucket_t with a type2 variable at the end?
(It looks like we have only one places where we allocate these, when I ignore the trunk log
bucket hacks... which would already break if some other bucket did the same trick)

We can then just rev serf_bucket_create() to set type and typ2 to the same variable.


Nope. We've never said buckets MUST be constructed with that function. Thus, users may be
constructing their own buckets, and they might not be large enough.




I'd be happy to redo our v2 testing, if we agree on the _is_v2() approach and using a special
bucket type for detection.





  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message