Skip to content
Browse files

Add a partial, preliminary IO::Async::File.

So far, only supports textual reading (slurp -> Promise, lines ->
Channel).
  • Loading branch information...
1 parent 525c5d0 commit 495602ba21a3701e6b6c6abd713260849fcdd174 @jnthn jnthn committed Aug 10, 2013
Showing with 60 additions and 0 deletions.
  1. +60 −0 src/vm/jvm/core/Threading.pm
View
60 src/vm/jvm/core/Threading.pm
@@ -455,6 +455,66 @@ my class ThreadPoolScheduler {
# This thread pool scheduler will be the default one.
$PROCESS::SCHEDULER = ThreadPoolScheduler.new();
+# Very basic asynchronous I/O support for files. Work in progress. Things that
+# would nomally return something scalar-ish produce a Promise. Things that
+# would normally return a (lazy) list produce a Channel.
+my class IO::Async::File {
+ has $!PIO;
+ has $.chomp = Bool::True;
+ has $.path;
+
+ proto method open(|) { * }
+ multi method open($path? is copy, :$r, :$w, :$a, :$bin, :$chomp = Bool::True,
+ :enc(:$encoding) = 'utf8') {
+ $path //= $!path;
+ my $mode = $w ?? 'w' !! ($a ?? 'wa' !! 'r' );
+ nqp::bindattr(self, IO::Async::File, '$!PIO',
+ nqp::openasync(nqp::unbox_s($path.Str), nqp::unbox_s($mode))
+ );
+ $!path = $path;
+ $!chomp = $chomp;
+ nqp::setencoding($!PIO, $bin ?? 'binary' !! NORMALIZE_ENCODING($encoding));
+ self;
+ }
+
+ method close() {
+ nqp::closefh($!PIO);
+ Bool::True;
+ }
+
+ method opened() {
+ nqp::p6bool(nqp::istrue($!PIO));
+ }
+
+ method slurp(:$bin, :enc($encoding)) {
+ self.open(:r, :$bin) unless self.opened;
+ self.encoding($encoding) if $encoding.defined;
+
+ if $bin {
+ die "Asynchronous binary file reading NYI"
+ }
+ else {
+ my $p = Promise.new;
+ nqp::slurpasync($!PIO, Str,
+ -> $str { $p.keep($str); self.close(); },
+ -> $msg { $p.break($msg); try self.close(); });
+ $p
+ }
+ }
+
+ method lines(:enc($encoding)) {
+ self.open(:r) unless self.opened;
+ self.encoding($encoding) if $encoding.defined;
+
+ my $c := Channel.new;
+ nqp::linesasync($!PIO, Str, $.chomp ?? 1 !! 0,
+ nqp::getattr($c, Channel, '$!queue'),
+ -> { $c.finish(); self.close() },
+ -> $msg { $c.fail($msg); try self.close(); });
+ $c
+ }
+}
+
# Schedules a piece of asynchronous work using the current scheduler, and
# returns a promise that represents it.
sub async(&code) {

0 comments on commit 495602b

Please sign in to comment.
Something went wrong with that request. Please try again.