Handle(3pm)

πŸ’– Coro::Handle πŸ’–

okay bestie, welcome to Coro::Handle, a page from the User Contributed Perl Documentation collection. it's giving non-blocking I/O with a blocking interface, and honestly? iconic.


✨ SYNOPSIS ✨

use Coro::Handle;

πŸ¦‹ DESCRIPTION πŸ¦‹

okay so first thing, no cap: this module is an AnyEvent user. that means you need to make sure you use and run a supported event loop, or nothing's gonna slay. periodt.

what it does: it implements IO-handles in a coroutine-compatible way. translation? other coroutines can keep running while reads or writes are blocked on the handle. nobody's stuck waiting in the group chat πŸ’…

how? it uses AnyEvent to wait for readable/writable data, which lets other coroutines run while one coroutine is just sitting there waiting for I/O. main character energy for the coroutine that does get to run.

important lore: Coro::Handle does NOT inherit from IO::Handle. instead it uses tied objects. yes, tied objects, we love a plot twist.

🫢 if at all possible, you should always prefer method calls on the handle object over invoking tied methods.

like this, bestie:

$fh->print ($str);         # NOT print $fh $str;
my $line = $fh->readline;  # NOT my $line = <$fh>;

why tho? because perl recurses within the interpreter when invoking tie magic, and that forces the (temporary) allocation of a (big) stack. so if you've got lots of socket connections and they happen to be waiting in e.g. <$fh>, then they would all have a costly C coroutine associated with them. not the vibe. 😭

🌸 the methods & friends 🌸

  • $fh = new_from_fh Coro::Handle $fhandle [, arg => value...] β€” creates a new non-blocking io-handle using the given perl-filehandle. returns undef if no filehandle is given. the only other supported argument is timeout, which sets a timeout for each operation. πŸŽ€
  • $fh = unblock $fh β€” a lil convenience function that just calls new_from_fh on the given filehandle. use it to replace a normal perl filehandle with a non-(coroutine-)blocking equivalent. glow up ✨
  • $fh->writable, $fh->readable β€” wait until the filehandle is readable or writable (and return true) or until an error condition happens (and return false). vibe check on the socket.
  • $fh->readline ([$terminator]) β€” similar to the builtin of the same name, but lets you specify the input record separator in a coroutine-safe manner (i.e. not using a global variable). paragraph mode is NOT supported β€” use "\n\n" to achieve the same effect. iykyk.
  • $fh->autoflush ([...]) β€” always returns true, arguments are being ignored (exists for compatibility only). might change in the future. so don't get attached πŸ™ˆ
  • $fh->fileno, $fh->close, $fh->read, $fh->sysread, $fh->syswrite, $fh->print, $fh->printf β€” work like their function equivalents, except read, which works like sysread. ngl you should not use the read function with Coro::Handle's β€” it will work, but it's not efficient. it's giving "technically fine, spiritually wrong".
  • connect, listen, bind, getsockopt, setsockopt, send, recv, peername, sockname, shutdown, peerport, peerhost β€” do the same thing as the perl builtins or IO::Socket methods (but return true on EINPROGRESS). remember, bestie: these must be method calls. πŸ‘‘
  • peeraddr, peerhost, peerport β€” return the peer host (as numerical IP address) and peer port (as integer). numbers, but make it cute.
  • ($fh, $peername) = $listen_fh->accept β€” in scalar context, returns the newly accepted socket (or undef), and in list context returns the ($fh, $peername) pair (or nothing). two moods, one method πŸ’…
  • $fh->timeout ([...]) β€” the optional argument sets the new timeout (in seconds) for this handle. returns the current (new) value.
⭐ 0 is a valid timeout, use undef to disable the timeout. don't come for me, that's just how it is.
  • $fh->fh β€” returns the "real" (non-blocking) filehandle. use this if you wanna do operations on the file handle that you can't do using the Coro::Handle interface. it's the raw unfiltered version πŸ”₯
  • $fh->rbuf β€” returns the current contents of the read buffer. this is an lvalue, so you can change the read buffer if you like. yes, you can just... do that.

you can use this function to implement your own optimized reader when neither readline nor sysread are viable candidates, like this:

  # first get the _real_ non-blocking filehandle
  # and fetch a reference to the read buffer
  my $nb_fh = $fh->fh;
  my $buf = \$fh->rbuf;

  while () {
     # now use buffer contents, modifying
     # if necessary to reflect the removed data

     last if $$buf ne ""; # we have leftover data

     # read another buffer full of data
     $fh->readable or die "end of file";
     sysread $nb_fh, $$buf, 8192;
  }

go off, write your own reader 🧚


πŸ’€ BUGS πŸ’€

  • Perl's IO-Handle model is THE bug.

no notes. that's the whole section. not me cackling 😭


🫢 AUTHOR/SUPPORT/CONTACT 🫢


okay that's the whole page bestie, you ate πŸ’… this was perl v5.40.1 documentation from 2025-03-21 β€” stay hydrated, close your filehandles, and remember: the IO-Handle model is THE bug. mwah πŸŽ€βœ¨

πŸ“¦ where this page comes from