cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: living without global variables

From: Daniel Stenberg <daniel_at_haxx.se>
Date: Thu, 1 Dec 2005 18:15:04 +0100 (CET)

On Tue, 29 Nov 2005, Bryan Henderson wrote:

>> Also, I'm not fond of the specific functions added for the single specific
>> items that (currently) have a global state or a field in the client object:
>> openssl, gnutls, sock, charset. I prefer a more extensible approach that
>> allows us to add a new subsystem tomorrow and remote one of the existing
>> the day after that, without breaking the API/ABI backwards compatibility.
>
> I presume you're thinking of a single function with named flags to select
> what it does. Note that this enables only binary compatibility.

It enables binary compatibility and backwards source compatibility. So that
when we add new options they won't break old applications, and removing
options won't either as long as the defines remain.

> At compile time, the compatibility characteristics look the same to me
> whether you add a new function name or add a new flag name.

Yes, but adding and removing functions to the API/ABI is a lot more expensive
operation than adding and removing flags. In code and in docs.

> But binary compatibility is good, and so is reducing symbol table clutter. I
> will try this:
>
> CURL_EXTERN void curl_client_use_global(CURLC *curlc, long flags);
>
> #define CURL_GLOBAL_OPENSSL ...
> #define CURL_GLOBAL_WINSOCK ...
>
> Ultimately, it will have to get messier because the user will be passing a
> handle for a private facility instead of just saying, "use the global
> facility."

I don't understand. Why is

   curl_client_use_global(curlc, CURL_GLOBAL_OPENSSL);

"messier" than

   curl_client_use_global_openssl(curlc);

? They both pass the exact same amount of information, just in different ways.

> That handle may not be representable as a generic type (e.g. void *), and
> even if it is, we may want to use a real type.

True, but us taking a flag or a specific function doesn't change that.

>> Is there really a need for gnutls global data?
>
> Well, I assume the GNU TLS designers wouldn't have provided such a heinous
> thing as gnutls_global_init(), and curl_global_init() wouldn't call it, if
> it weren't necessary.

Indeed. Sorry, I forgot there was such a one. It is kind of funny that they
couldn't avoid globals either.

>> Further, is there a need for the curl_client_global_xxx_ok() public
>> functions?
>
> I didn't intend for these to be public. They should go in clientif.h
> instead of client.h, right?

Yes, and they shoule have a Curl_ prefix (instead of curl_) and not use
CURL_EXTERN.

> But that reminds me of something I forgot to deal with: If the user is going
> to be responsible for initializing global stuff, he should have a way to
> determine what global stuff libcurl would like to use.

Now that can become a fun excersize.

> In particular, if a user wants to do SSL connections, the libcurl he links
> to might be built for OpenSSL or might be built for GNU TLS, and the user
> needs to know at compile time which one it is so he can #include the right
> SSL library interface and call the right initialization functions.

Unfortunately that goes pretty much in the opposite direction of my efforts to
enable libcurl users to be completely unknowing about what particular SSL
library libcurl uses.

But I don't see how it can be avoided if the app really wants to do the global
inits by itself.

> This seems to call for an option on curl-config to tell you what facilities
> it uses.

Yes, but curl-config does not work on all platforms libcurl works on... We
could perhaps have a function that can return a bitmask with the global flags
that this particular libcurl uses.

-- 
  Commercial curl and libcurl Technical Support: http://haxx.se/curl.html
Received on 2005-12-01