Let's say I have a thread:
sub new {
my $class = shift;
my $self = ref $class || $class;
bless { 'read_set' => IO::Select->new,
'write_set' => IO::Select->new,
'error_set' => IO::Select->new }, $self;
}
sub start {
my $self = shift;
$self->{'thread'} = threads->create(\&worker_thr, $self);
$self->{'thread'}->detach;
}
sub worker_thr {
my $self = shift;
while(1) {
my($read_active, $write_active, $error_active) =
IO::Select->select(
$self->{'read_set'},
$self->{'write_set'},
$self->{'error_set'},
undef
);
}
}
Since I have provided no timeout to select()
and it blocks indefinitely until activity is detected on one of the descriptor (well, "handle") sets, what happens if another thread modifies the contents of the sets (e.g. adds a new socket for polling)?
Is it implemented in a thread-safe manner, relative to the Perl POSIX threads implementation?
If not, I suppose I can stick the blocking select()
call in a block with its own scope and lock the sets or, more cleanly, the entire package data. What is the best way to wake select()
up to return, from another thread so that the contents of the sets can be manipulated? Thread-specific signal? Semaphore? Suggestions welcome.
Thanks muchly!
Edit: Well, thread-specific "signal" is out. As explained here ( http://perldoc.perl.org/threads.html ): "Correspondingly, sending a signal to a thread does not disrupt the operation the thread is currently working on: The signal will be acted upon after the current operation has completed. For instance, if the thread is stuck on an I/O call, sending it a signal will not cause the I/O call to be interrupted such that the signal is acted up immediately."
That still leaves me wondering how I should handle the issue of waking select()
up in a thread if I want it to block indefinitely instead of returning after a fixed timeout.