I'm pulling my hair out, and still can't figure a decent way to do this out... What I want to do is to create a program that somehow creates subprocesses (via threads, fork() or whatever), with the ability to have a hash shared between them.
Specifically, I need to share two objects and a hash. The children then needs to be able to set hash keys that points to object instances... I think.
A bit more verbose:
I'm writing a caching DNS server, for the sole purpose of learning. At the moment, it works great as a passthrough (the caching isn't implemented yet, due to this), but only handles one request at a time. If you throw a bunch of slow queries, the last ones handled will be REALLY slow instead of just "slow".
I tried to set up some basic caching (for testing purposes only, since the TTL is ignored etc etc), by saving the Net::DNS::Packet for the answer into a hash, i.e.
Code:
if (defined $cache{$q->string}) {
print STDERR "Got it cached! NOT sending to upstream server!\n" if DEBUG;
$answer = $cache{$q->string};
}
else {
print STDERR "Sending request to upstream server...\n" if DEBUG;
$answer = $resolver->send($in_req);
say STDERR " Done" if DEBUG;
$cache{$q->string} = $answer;
}
That works too, until I try to add the concurrency part... With fork(), I tried using IPC::Shareable, which worked until the hash grew, and the program died with an out-of-semaphores error.
Then I spent quite a lot of time to recompile perl with ithreads, only to run in to the snag that "Thread 1 terminated abnormally: Invalid value for shared scalar at test.pl line 60"
Line 60 is "$cache{$q->string} = $answer", in other words, setting a key in the shared hash to a Net::DNS::Packet reference.
Is there an easy way around this? Heck, how do the other similar programs work?!