rendler has asked for the wisdom of the Perl Monks concerning the following question:

The following code is producing :
Connection from 127.0.0.1:2002 Invalid value for shared scalar at ./threads.pl line 47.
Some help would be very appreciated :)
#!/usr/bin/perl -w $|++; use strict; use IO::Socket; use threads; use threads::shared; our %clients : shared; our $i : shared = 0; my $log = "$ENV{HOME}/games/aardwolf/.aard.log"; my $port = shift; my $server = IO::Socket::INET->new( LocalPort => $port, Proto => 'tcp', Listen => 1 ) or die "Couldn't be a tcp server on port $port: $@\n"; threads(\&handle_clients($server))->detach; open LOG, $log or die $!; while (my $line = <LOG>) { lock %clients; for my $i (keys %clients) { unless (defined $clients{$i}->connected) { delete $clients{$i}; next; } $clients{$i}->print($line); } } close LOG; sub handle_clients { my $server = shift; while (my $client = $server->accept) { lock $i; ++$i; my $client_addr = peerinfo($client); print "Connection from $client_addr\n"; lock %clients; $clients{$i} = $client; } } sub peerinfo { my $client = shift; my $other_end = getpeername($client); my ($port, $iaddr) = unpack_sockaddr_in($other_end); my $ip = inet_ntoa($iaddr); return "$ip:$port"; }

Replies are listed 'Best First'.
Re: Threading problem with IO::Socket
by BrowserUk (Patriarch) on Jul 13, 2003 at 15:24 UTC
    The first thing worth noting is that sockets, like other handles (STDIN, STDOUT etc) are process global enitities, and are therefore implicitly and inexorably shared by all threads within a process.

    The caveat is that when you use a class like IO::Socket to manage a process global resource, it uses memory to retain state. This memory is not implicitly shared. Further, the mechanism by which perl locates methods applicable to objects is through the blessing of the object handle which is a memory reference. The problem here is that even if the routines that implement those methods are re-entrent, unless the state represented by the object handle are themselves correctly shared (and are shareable!), then invoking methods across threads is going to give rise to problems. This is why objects are not shareable.

    The upshot is, that the main problem of your code lies in the concepts underlying it. Why do you want to share a process global resource between threads? What are you trying to achieve? Whatever it is can probably be achieved, but it would take and understanding of your goals before the 'right' approach to the problem could be discovered.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


Re: Threading problem with IO::Socket
by antirice (Priest) on Jul 13, 2003 at 06:41 UTC

    Don't know if this will help but the reason it returns the "Invalid value..." is because you're assigning a ref to unshared data. Of course, I've never tried this with a Socket (which is basically a blessed glob), so I don't even know if this will fly.

    $client{$i} = &share($client);

    The & is there to skip over those pesky prototyping errors. Hope this helps.

    antirice    
    The first rule of Perl club is - use Perl
    The
    ith rule of Perl club is - follow rule i - 1 for i > 1

      Kinda crashed and burned:
      Cannot share globs yet at ./threads.pl line 47.

        Didn't think you could. I was searching for the source for threads::shared as I thought you could only share [\][$@%]. Of course, now that I've looked at the documentation there's no mention of globs. I don't see any way around this. Guess you'll need to wait for 5.8.1. Sorry :-(

        antirice    
        The first rule of Perl club is - use Perl
        The
        ith rule of Perl club is - follow rule i - 1 for i > 1

        Robert,

        have you tried forks.pm:
        http://search.cpan.org/author/ELIZABETH/forks-0.03/lib/forks.pm

        I seems that this is meant to do it!

        But to install forks you need load.pm from the same author:

                http://search.cpan.org/author/ELIZABETH/load-0.05

        I'd like to share results and suggestions, pls mail me directly:

        g o o l y    a t    g m x    d o t    a t

        Good evening to down under (from/to Austr(al)ia),
        carl

A reply falls below the community's threshold of quality. You may see it by logging in.