#### WARNING: THIS CODE IS BROKEN. DO NOT USE #### #! perl -slw use strict; use threads; use threads::shared; our $BUFSIZE ||= 2**20; open my $fh, '+< :raw', $ARGV[ 0 ] or die $!; our $buffer1 : shared = ''; our $buffer2 : shared = ''; our $p1 :shared = 0; our $p2 :shared = 0; my $done : shared = 0; { lock $buffer2; async { while( not $done ) { { lock $buffer1; $p1 = $p2 + length $buffer2; sysseek $fh, $p1, 0; $done = !sysread $fh, $buffer1, $BUFSIZE; } { lock $buffer2; $p2 = $p1 + length $buffer1; sysseek $fh, $p2, 0; $done = !sysread $fh, $buffer2, $BUFSIZE; } } print "Thread done: $done"; $done = 1; }->detach; } sleep 1; while( not $done ) { { lock $buffer1; # A visible, reversable transformation for testing! $buffer1 =~ tr[0*][*0]; # sysseek $fh, $p1, 0; syswrite $fh, $buffer1; } { lock $buffer2; $buffer2 =~ tr[0*][*0]; sysseek $fh, $p2, 0; syswrite $fh, $buffer2; } } close $fh; #### #! perl -slw use strict; use threads; use Thread::Queue; our $BUFSIZE ||= 2**20; open my $fh, '+< :raw', $ARGV[ 0 ] or die $!; my $size = -s $fh; my $Qin = new Thread::Queue; my $Qout= new Thread::Queue; async { my $buffer; while( sysread $fh, $buffer, $BUFSIZE ) { $Qin->enqueue( $buffer ); sleep 1 while $Qin->pending > 10; } $Qin->enqueue( undef ); }->detach; my $Tout = async{ sleep 1 until $Qout->pending; sysseek $fh, 0, 0; while( my $out = $Qout->dequeue ) { syswrite $fh, $out; } }; sleep 1 until $Qin->pending; while( my $in = $Qin->dequeue ) { $in =~ tr[0*][*0]; $Qout->enqueue( $in ); } $Qout->enqueue( undef ); $Tout->join; close $fh;