Your skill will accomplish what the force of many cannot |
|
PerlMonks |
WWW::Curl and making it thread safeby lsuchocki (Novice) |
on Feb 18, 2016 at 03:18 UTC ( [id://1155516]=perlquestion: print w/replies, xml ) | Need Help?? |
lsuchocki has asked for the wisdom of the Perl Monks concerning the following question: Oh Perl Monks, I plead for your insight.. My app uses WWW::Curl::Multi (libcurl) to perform web tasks which are handled, among many other things, in a super loop. I've recently added a piece of code which fork()s to perform an occasional long-running task, which I do not want to block my main loop with. Works great. On Linux. Upon testing the same code under Windows (Strawberry Perl) with the newly added code which forks, perl crashes. Debugging shows me if I don't fork(), it doesn't crash, and if I don't "WWW::Curl::Multi->new();" it doesn't crash. Knowing that Windows emulates fork() with interpreter threads, I'm guessing the WWW::Curl library is not thread safe.
This was confirmed with the following bare-minimum test cases:
Which yields:
And under Linux:
Which yields (under GDB):
Now, I don't need any curl resources within my child/thread, it's only used in the main program (technically another .pm), but the object created is globally scoped and has a member with a WWW::Curl object. So I don't think I can keep it hidden from my child/thread. Curl itself is supposed to be thread-safe, with the exception of the curl_global_init. I'm pretty sure that's not the issue though, since the child does not call it. Unless it's being automatically called a second time by the BOOT: XS syntax on the thread creation? I believe that when I fork under Win32/thread under Linux, my object may be free()d by the DESTORY XS methods when I exit/join the thread? And I probably need to prevent curl_global_cleanup() from being called when the thread exits in the .pm END{} block... ?? So... this is where it gets fuzzy for me. I'm a strong C programmer, but there's a learning curve with perl's XS. Are there any other modules out there which properly deal with these sort of situations which I may learn / copy from? I've spent all day reading perlthrtut, perlguts, perlmod, Example::CLONE and others and ended up with a nasty headache.. Most humbly, Is the solution simply to (in reference to the above examples):
This seems to prevent perl from crashing, and the double DESTROY, however, with the fork() example under windows, the END{} curl_global_cleanup() is called twice, in the thread and in the parent, where in the thread->create()->join() it is only called once..... Is this a safe workaround to what I'm seeing?
Back to
Seekers of Perl Wisdom
|
|