my $head = 0; # Can only be modified by the lone writer thread my $tail = 0; # Can only be modified by the lone reader thread my $size = 4; # Can hold one less than $size my @buf = (undef) x $size; # Can only be called by the lone reader thread sub is_empty { return $tail == $head; } # Can only be called by the lone reader thread sub dequeue { return () if is_empty(); my $val = $buf[$tail]; $tail = ( $tail + 1 ) % @buf; return $val; } # Can only be called by the lone writer thread sub is_full { return ($head + 1) % @buf == $tail; } # Can only be called by the lone writer thread sub enqueue { my ($val) = @_; return 0 if is_full(); $buf[$head] = $val; $head = ( $head + 1 ) % @buf; return 1; } #### package Data::RingBuffer; sub new { my ($class, $size) = @_; return bless({ head => 0, tail => 0, buf => [ (undef) x $size ], }, $class); } sub is_empty { my ($self) = @_; return $self->{tail} == $self->{head}; } sub dequeue { my ($self) = @_; my $buf = $self->{buf}; return () if $self->is_empty(); my $val = $buf->[$self->{tail}]; $self->{tail} = ( $self->{tail} + 1 ) % @$buf; return $val; } sub is_full { my ($self) = @_; my $buf = $self->{buf}; return ($self->{head} + 1) % @$buf == $self->{tail}; } sub enqueue { my ($self, $val) = @_; my $buf = $self->{buf}; return 0 if $self->is_full(); $buf->[$self->{head}] = $val; $self->{head} = ( $self->{head} + 1 ) % @$buf; return 1; }