It is not clear what you are trying to do, so I don't know what would be
similar to it (or why you would expect threads or forks to make things
better rather than worse; or why locking on a socket would be necessary in
the absense of forking or threads.)
Presumable the problem arises when you use your socket. But you haven't
shown us anything that uses the socket. Is this a write-only socket?
How are messages delimited?
Sorry, I was trying to keep my example concise but I guess I made it to
concise.
I am attempting to create a 'Member' object that represents a member of
a club. Lets say a gardening club. Members have attributes that are
stored on a telnet server called Gps and I am using an overridden
Class::Accessor object to get/set those attributes. The telnet server
requires that the Members numeric ID attribute be set prior to
getting/setting a Members attribute (address for example).
So, if I have 30,000 'Member' instances all sharing a single socket I
am afraid that the 'member_id' state of the socket will be changed by
another 'Member' instance ($b) before the 'address' attribute of the
first instance ($a) is set. Is this a valid concern?
<---------------------------------------------------------------------->
package Gps;
use base qw(Class::Accessor);
use IO::Socket;
use Error qw
try);
# Declare class variables.
my $gpsclientport = 1409;
my $remote_port = 6635;
my $peer_addr = 'gps.spanky.com';
my $gps_socket;
try {
$gps_socket = IO::Socket::INET->new(PeerAddr => $peer_addr,
PeerPort => $remote_port,
Proto => 'tcp',
Type => SOCK_STREAM) or throw Error::Simple("Can't bind socket\n");
}
catch Error with {
$E = shift;
print STDERR "File ", $E->{'-file'}, $E->{'-text'}, " \n";
}
sub get {
my ($self, $key) = @_;
# get the desired value by key
@response = $self->_doCommand("get $key");
$value = join("", grep(!/^$key:/, @response));
return $value;
}
sub set {
my ($self, $key, $value) = splice(@_, 0, 3);
# set the desired value by key/value
@response = $self->_doCommand("set $key $value");
$value = join("", grep(!/^$key:/, @response));
return $value;
}
sub _doCommand {
($self, $command) = @_;
my @response;
try {
# Check that the socket is available
$gps_socket or throw Error::Simple("Can't bind : $gps_socket\n");
# set the user by user_id
print $gps_socket "ID $self->user_id", "\r\n";
#member_id state could be changed here by another Member instance
#calling the socket at the same time??????????
# print to the GPS socket
print $gps_socket $command, "\r\n";
while (<$gps_socket>) {
chop;
last if /^###/;
push (@response, $_);
}
throw Error::Simple("@response") if (grep(/Error/i, @response));
}
catch Error with {
$E = shift;
print STDERR "$E->{-text}\n";
}
finally {
return @response;
};
}
1;
<---------------------------------------------------------------------->
package Member;
use Gps;
sub new {
my $class = shift;
my $self = {};
$self->{'Gps'} = Gps->new;
bless ($self, $class);
return $self;
}
1;
<---------------------------------------------------------------------->
#Meanwhile in some other code
use Member;
$a = Member->new;
$a->{'Gps'}->user_id(323775);
$a->{'Gps'}->address("1234 Fake St.");
<---------------------------------------------------------------------->
#Meanwhile in some other code
use Member;
$b = Member->new;
$b->{'Gps'}->user_id(323776);
$b->{'Gps'}->address("666 Devil St.");
<---------------------------------------------------------------------->