MemoryViewを扱う時のメモリーの解放について
https://gyazo.com/776bc5fc50deaeba55198ac6a73e9831
MemoryViewから取り出したデータを扱った後にrb_memory_view_releaseするわけだけど
それをrb_ensureでやろうと思うとめんどくさくない?
ensure_funcにrb_memory_view_tを渡したいんだけどVALUEしか受け付けないよね。
単に解放したいんであればselfを渡して、中でrb_memory_view_getするんでもいいかもだけど、
条件付きで解放したい場合はその条件も渡したいわけで、そのためだけにArrayとかラッパークラスを作るのかねえ・・・
「あるオブジェクトがMemoryViewをエクスポートする時はそれを使い、エクスポートしない時はVALUEの操作にフォールバックする」という処理を書いていると、
「MemoryViewを使っているかいないか」という条件に応じてrb_memory_view_releaseをするか(逆にxfreeするか)しないか決めないといけない。
こうして愚痴を書いていたらちょっと問題が整理されたな。
MemoryViewとフラグ一個だけならArrayでもいい気がしてきた。
おまけにbody_funcに渡す引数をラップするのもめんどくさいな、こっちの方が問題だわ・・・
Cでやりたいから拡張にしているわけで、扱いたいCの変数全部をラップするクラスを定義することになるのか・・・?
これも愚痴ってたら整理されてきたけど、一個だけ追加でクラス定義するのでいけそうだわ。
なるほど、Cの構造体をVALUEにキャストしてしまうというテクニックがあるのか。。。
static VALUE
udp_connect(VALUE self, VALUE host, VALUE port)
{
struct udp_arg arg = {.io = self};
arg.res = rsock_addrinfo(host, port, rsock_fd_family(rb_io_descriptor(self)), SOCK_DGRAM, 0, Qnil);
int result = (int)rb_ensure(udp_connect_internal, (VALUE)&arg, rsock_freeaddrinfo, (VALUE)arg.res);
if (!result) {
rsock_sys_fail_host_port("connect(2)", host, port);
}
return INT2FIX(0);
}
static VALUE
chdir_path(VALUE path, bool yield_path)
{
if (chdir_alone_block_p()) {
struct chdir_data args;
args.old_path = rb_str_encode_ospath(rb_dir_getwd());
args.new_path = path;
args.done = FALSE;
args.yield_path = yield_path;
return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args);
}
else {
char *p = RSTRING_PTR(path);
int r = IO_WITHOUT_GVL_INT(nogvl_chdir, p);
if (r < 0)
rb_sys_fail_path(path);
}
return INT2FIX(0);
}