libuv の Perl バインディング

気分転換プロジェクトとして、libuvのPerlバインディングを書いている。

typester/p5-UV - GitHub

現状、timerとtcp周りを一通り実装したところ。

実装は愚直にlibuvの関数とperlの関数を1:1に(uv_tcp_init(...)UV::tcp_init(...)というような形で)マッピングしている。 この実装はlow level APIと位置づけ、その上に使いやすい高レベルなインタフェースをPerl上で用意したいつもり。

このlow level APIをつかったTCP echo serverはこんな感じになる:

use strict;
use warnings;

use UV;

my $server = UV::tcp_init();
UV::tcp_bind($server, '0.0.0.0', 3000)
    && die 'bind error: ', UV::strerror(UV::last_error());

UV::listen($server, 10, sub {
    my $client = UV::tcp_init();
    UV::accept($server, $client) && die 'accept failed: ', UV::strerror(UV::last_error());

    UV::read_start($client, sub {
        my ($nread, $buf) = @_;

        if ($nread < 0) {
            my $err = UV::last_error();
            if ($err != UV::EOF) {
                warn 'client read error: ', UV::strerror($err);
            }
            UV::close($client);
        }
        elsif ($nread == 0) {
            # nothing to read
        }
        else {
            UV::write($client, $buf, sub {
                my ($status) = @_;

                if ($status) {
                    warn 'client write error: ', UV::strerror(UV::last_error());
                    UV::close($client);
                }
            });
        }
    });

}) && die 'listen error: ', UV::strerror(UV::last_error());

UV::run();

見てわかるようにperlモジュールとしての使いかってはわるいが、libuvを使い慣れた人なら迷いなく使うことが出来るようになっている。 これは僕にとっては発見だった。

また、このサンプルをみてもわかるようにlistenとかacceptとかまでラップしている関係上、libuvをAnyEventのバックエンドとしてつかうのは現状は無理そう。

libuv自体はWindowsでも動くはずだが、メインマシンをAirにして以来Windows環境を仮想環境でも持ち歩いていないため確認できていない。 Windows対応してくれる人募集!

開発を始めるためのステップ:

$ cpanm Module::Install
$ cpanm Module::Install::XSUtil

$ git clone git://github.com/typester/p5-UV.git
$ cd p5-UV
$ git submodule update --init
$ perl Makefile.PL
$ make
$ make test
by typester / at 2011-12-01T11:38:00 / perl · libuv / Comments(0)