cURL / Mailing Lists / curl-library / Single Mail

curl-library

Threading and general usage in C++

From: Gabriel Ambuehl <gabriel_ambuehl-curl_at_buz.ch>
Date: Thu, 19 Apr 2001 20:00:50 +0200

-----BEGIN PGP SIGNED MESSAGE-----

Hello,
I've just started using libcurl as I couldn't find any other lib that
sanely implements HTTP(S) and FTP (although I wouldn't care to have to
use two libs for this, if only HTTPS is supported, due to company
regulations, GPL code isn't viable[1], LGPL is fine though).

I've got to write some sort of server monitoring system in C++
(started in
Python but it turned out to be way too slow[2]) and figured about the
only solution to get it working in a sane manner is to use threading
(having a seperate process for every resource to monitor is a no
starter as to RAM usage) as this at least saves me from worrying about
the whole scheduling concept.

After some research, I decided to go with Gnu's CommonC++ (any other
recommendations would be greatly appreciated) for the threading stuff
(
and figured that it has a URL lib which I couldn't get to work ;-)
which
went surprisingly easy. But when I tryed to throw the stuff together,
I encountered two problems (one very serious, the other probably
something
I've overlooked):

//(everything inline for ease of reading))
//to compile on FreeBSD: g++ -Wall -L/usr/local/lib
- -L/usr/local/include -pthread -lxml -D_THREAD_SAFE
- -I/usr/local/include -lccstd -lccxx -lcurl -lcrypto -lssl

#include <iostream.h>
#include <stdlib.h>
#include <cc++/thread.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
// We need sleep()
#include <unistd.h>

//Subclass of Common C++ Thread class
class myCURLThread : public Thread
{
        private:
                unsigned int interval, number_of_checks;
                char *url;
                CURL *curl;
                CURLcode res;

        public:
                inline void Run(void)
                {
                        while (number_of_checks < 1000)
                        {
                                //Sleep() is provided by CC++
                                Sleep(interval);
                                //no segfault without the next line
;-)
                                cout << check();
                                number_of_checks++;
                                //merely some attempt to measure
                                //libcurl performance: I was pleased,
                                //more than enough for my purpose
                                cerr << number_of_checks << endl;
                        }
                        return;
                }

                }
                inline int check(void)
                {
                         //docs say one has to set the options again
                         //after each request, but I probably should
                         //close the connection anyway after each
                         //request, I use cout to see if shit happens
                         cout << curl_easy_setopt(curl,
CURLOPT_NOPROGRESS, 1);
                         cout << curl_easy_setopt(curl, CURLOPT_URL,
url);
                         //this should run as daemon. i.e. we don't
                         //want to have any output unless told to do
                         //so
                         cout << curl_easy_setopt(curl, CURLOPT_MUTE,
1);
                         cout << curl_easy_setopt(curl,
CURLOPT_WRITEHEADER, stdout);
                         curl_easy_perform(curl);
                         cout << "leaving check()" << endl;
                         return 0;
                }
};

int main(int argc, char **argv)
{
         int argv_index;
         myCURLThread mycurl[atoi(argv[3])];
         //set params
         mycurl[0].setInterval(atoi(argv[2]));
         mycurl[0].setUrl(argv[1]);
         //create thread and call mycurl[0].Run()
         mycurl[0].Start();

         mycurl[1].setInterval(atoi(argv[2]));
         mycurl[1].setUrl(argv[1]);
         sleep(100);
         return EXIT_SUCCESS;
}

On FreeBSD, this compiles with some warnings about libc not being
THREAD_SAFE but despite, it works. Now trouble starts if one adds a
mycurl[1].Start() (after the second setUrl) which results in an
immediate
segfault and core dump that is obviously related to libcurl since it
won't occur if check
isn't called in Run() (run is some sort of main() for the thread). Now
is there any halfway reliable information about the thread safety of
libcurl (Daniel states thinks it should be, but that he didn't test)?

This was the serious problem, the other one isn't really that serious
but still disturbing: despite the use of

cout << curl_easy_setopt(curl, CURLOPT_MUTE, 1);

curl_easy_perform() will dump everything to the console (a short look
at
an example and compiling it using normal C pointed out that it
actually works in C, but doesn't seem to do so in C++, the other
config stuff works, though).

Best regards,
 Gabriel

[1] Our managers always think they could probably sell inhouse stuff
which obviously wouldn't work with GPL code. I've got my doubts on the
feasibility of this but...

[2] I wonder whether I should try to write some Python wrapper to the
lib to see if performance would improve.

-----BEGIN PGP SIGNATURE-----
Version: PGP 6.0.2i

iQEVAwUBOt8ZxsZa2WpymlDxAQFvwgf/WKlROp6Y6D8+ma/5MUlMxRF8cLkb21oR
jXuQ/wBA7kSbGEaUNW7y/cWt7sY+RUzqsMbLLDsW5kxnidwdyKz1IcE6Qm5hPIuJ
EFXlaeEMiiAv1atGNx7dwCcUIO+lPu87i875qwAs6kKeGdjj1H8ZvMH0cUyAzknR
eaPsRAxKvlY7W3CC1OuJUtmo+XDvT1qj4+bhvILBBJmnuIkiSM1sqQsQPhirkUro
XswUUYZDreBh+R5bsDyNgfoVfZI25ro6j8rgwPnp5RY9lRTIhvZE/AQ7PRi6LsQg
fks5gRoDGZaueb9HMA6ivjcluhSQF2d0Yze0yR31cdDj18Y43gbu0Q==
=l9df
-----END PGP SIGNATURE-----

_______________________________________________
Curl-library mailing list
Curl-library_at_lists.sourceforge.net
http://lists.sourceforge.net/lists/listinfo/curl-library
Received on 2001-04-19