cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: living without global variables

From: Bryan Henderson <bryanh_at_giraffe-data.com>
Date: Tue, 29 Nov 2005 18:14:50 +0100

>I'm not saying it is better, but an alternative approach would of
>course be to assign the 'client object' to the easy handle with a
>CURLOPT_* option after it was created. It would remove the need for
>curl_easy_init_c()...

In my opinion, it is cleaner for a session to be permanently owned by
a client, whereas in the CURLOPT_x method, you switch clients
midstream. There seems to be greater opportunity for confusion and
for coding errors. But I believe there is also a practical reason
there must be a new easy_init function: curl_easy_init() will call
curl_global_init(), and the whole point of this is to stop
curl_global_init() from running. We could maybe move that failsafe
call to later, but it would be kind of messy.

>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. At compile time, the compatibility characteristics
look the same to me whether you add a new function name or add a new
flag name.

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." 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.

>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. But I know nothing of GNU TLS. Are
you suggesting that gnutls_global_init() is not necessary, or are you
talking about something else?

>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?

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. 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. This seems to call for an option on
curl-config to tell you what facilities it uses.

Any alternative thoughts?

-- 
Bryan Henderson                                    Phone 408-621-2000
San Jose, California
Received on 2005-11-29