Thanks for the feedback. I think I managed to lock a separate private variable of the object and now can use a socket inside the object that is not shared and therefore does not cause a conflict.
This is a fully working perl sample script:
#!/usr/bin/perl
use strict;
use warnings;
use threads;
use threads::shared;
{
package Foo;
use threads::shared;
use constant INDENT => "\t\t\t\t\t\t\t\t";
sub new {
my $class = shift;
my %this;
$this{_socket} = shift;
$this{_sendBuffer} = [];
# TBD: Why does this not work?
# my %this = {
# _socket => shift,
# _sendBuffer => [],
# };
share ($this{_sendBuffer}); # make this a shared variable t
+o allow main thread to lock & manipulate this
return bless \%this, $class;
}
sub serve {
my $this = shift;
{ # scope for lock on $Foo->{_sendBuffer}
print INDENT . "object thread: 1st lock attempt\n";
lock ($this->{_sendBuffer});
print INDENT . "object thread: 1st lock acquired...";
push $this->{_sendBuffer}, "datagram " . scalar (@{$this->
+{_sendBuffer}});
sleep (1);
print " and released!\n"; # pretend to release lock
+ before going out of scope
} # release lock
sleep (1);
{ # scope for lock on $Foo->{_sendBuffer}
print INDENT . "object thread: 2nd lock attempt\n";
lock ($this->{_sendBuffer});
print INDENT . "object thread: 2nd lock acquired...";
push $this->{_sendBuffer}, "datagram " . scalar (@{$this->
+{_sendBuffer}});
sleep (1);
print " and released!\n"; # pretend to release lock
+before going out of scope
} # release lock
}
}
my $foo = new Foo();
my $thr1 = threads->create(sub { $foo->serve() });
{ # scope for lock on $foo
print "main thread: 1st lock attempt\n";
lock ($foo->{_sendBuffer});
print "main thread: 1st lock acquired...\n";
print " foo send buffer size: " . scalar (@{$foo->{_sendBuffer}
+}) . "\n";
sleep (1);
print "main thread: 1st lock released!\n";
} # release lock
sleep (1);
{ # scope for lock on $foo
print "main thread: 2nd lock attempt\n";
lock ($foo->{_sendBuffer});
print "main thread: 2nd lock acquired...\n";
print " foo send buffer size: " . scalar (@{$foo->{_sendBuffer}
+}) . "\n";
sleep (1);
print "main thread: 2nd lock released!\n";
} # release lock
$thr1->join(); # for some reason, this calls the destructor of
+foo (if present): so the thread obtained a copy of foo to work with?
print "main thread: object thread joined\n\n";
my $index = 0;
foreach my $item (@{$foo->{_sendBuffer}}) { # loop through contents
+ of sendBuffer
print "foo->{_sendBuffer[$index]}: $item\n"; # output sendBuf
+fer contents
$index++;
}
undef ($foo); # destroy object
I know, I am not really using a socket here - this sample was designed to find a way to use a "mutex" inside an object without locking the whole object. This is accomplished, and from my larger project I can now use a socket in the object.