cURL / Mailing Lists / curl-library / Single Mail

curl-library

living _with_ global variables

From: Bryan Henderson <bryanh_at_giraffe-data.com>
Date: 5 Jan 2006 03:39:17 +0000

I didn't see a response to the post below.

It nets out to: lets make curl_global_init() and curl_global_cleanup()
do a reference count.

I could put together a patch for this (along with a paragraph in the
manual about how to properly use them in a modular, threaded program)
pretty quickly if it's an acceptable direction. It's like 10 lines of
code.

>I have an alternative to propose for the issue of global variables in
>libcurl and their effect on modularity.
>
>Eliminating global variables from GnuTLS turned out to be fairly difficult,
>partly because there are a _lot_ of functions that need a context argument
>added, and partly because GnuTLS maintainers are lukewarm to the basic idea
>that life without global variables is better, and propose the alternative
>below.
>
>But the global variables in GnuTLS, and OpenSSL, and I presume the other
>components that libcurl uses, are special in that they are all effectively
>built-in constants, except for the fact that there has to be a library call
>at some point to set them up. IOW, if the program/library loader were
>smarter, it could set these up as real constants.
>
>So this means the library can be used by multiple independent modules,
>all calling global_init() and global_term(), as long as global_init()
>and global_term() maintain a reference count and do their thing only on
>the first and last call, respectively.
>
>Now the problem with the reference count is that it isn't thread-safe.
>Two independent modules running in separate threads might call
>global_init() separately and make a mess.
>
>But thread-safe isn't essential for these routines, because they can be
>called at the very beginning and end of a program, when it is only one
>thread. The code at that level doesn't necessarily know that this library
>will be used and thus needs to be initialized, but that requirement can
>propagate up through each layer's own global_init() function.
>
>libcurl already has that thread-unsafe global init function, so it's
>all set for this paradigm but for one thing: It doesn't do the
>reference count. It has a flag "I've been initialized." If that
>could be changed to "I've been initialized N times", and
>curl_global_init() conspicuously documented as thread-unsafe (to the
>greatest degree -- you must execute it when there is no other thread
>in the program doing anything, not just no other thread using
>libcurl), we'd have a solution to the modularity problem.
>
>The fail-safe global init in curl_easy_init() would have to get
>messier -- it would have to do its thing only if the init count is 0.
>
>This is kind of ugly compared to private contexts, especially in an
>object-oriented program, but it's really easy.
>
>For dynamically loaded libraries, I believe this isn't any better or
>worse than what we have today.
>
>Does this work? Have I missed something?
Received on 2006-01-05