ruby/perl のsyswrite について話したあとばたんと寝てたら、寝てる間に ruby コミッタと linux kernel コミッタがやってきて write(2) の制約であることが明らかになっていた

ruby/perl のsyswrite について話したあとばたんと寝てたら、寝てる間に ruby コミッタと linux kernel コミッタがやってきて write(2) の制約であることが明らかになっていた
28
tagomoris @tagomoris

"If write() is interrupted by a signal after it successfully writes some data, it shall return the number of bytes written."

2013-03-15 02:03:34
tagomoris @tagomoris

あああ、ってことはさっきの俺の fluent-agent-lite のコードは正しいな

2013-03-15 02:04:08
tagomoris @tagomoris

全データが書き込めたかどうかは(シグナルを気にするなら)blocking modeでもチェックしないといけないが、正の書き込みバイト数が帰ってきていてかつそれが書き込み要求サイズより小さかったとしても、それがシグナル由来であるかどうかを気にする必要はない

2013-03-15 02:05:17
ふみやす@シェルまおう(自称でない) @satoh_fumiyasu

@frsyuki 成功します。write 途中の原因がシグナルかの判定は、シグナルハンドラーで受信フラグをセットして、write が途中で返ってきたときにそれを見る、でできるかと思いますが、そんな実装見たことあったかな。シグナル受信で write を途中で放棄したい理由は?

2013-03-15 02:27:00
Sadayuki Furuhashi @frsyuki

@satoh_fumiyasu @tagomoris 基本的にはシグナルを受け取っても継続させたいですね。個人的には単純にユーザー空間でループを回せばいいんでは?派です。

2013-03-15 02:30:54
tagomoris @tagomoris

@frsyuki @satoh_fumiyasu それで正しいんだと思います。これっすね。 http://t.co/pMksEt5aLj シグナル自体はどっちにしろどこかでトラップしないとプロセス落ちるだけだし。

2013-03-15 02:33:05
ふみやす@シェルまおう(自称でない) @satoh_fumiyasu

@frsyuki @tagomoris なら write(2) は指定バイト未満で返る可能性があることを前提にループするだけです。ただし、wirte が -1 が返したら errno!=EINTR ならエラーで抜ける。https://t.co/ZFOW3gPqbG

2013-03-15 02:38:52
ふみやす@シェルまおう(自称でない) @satoh_fumiyasu

@satoh_fumiyasu @frsyuki @tagomoris システムコールがシグナルで割り込まれても勝手に再開するように、シグナルに SA_RESTART フラグ付けておく、という方法も。

2013-03-15 02:41:45
ふみやす@シェルまおう(自称でない) @satoh_fumiyasu

read(2), write(2) を使った処理はどう実装すべきか、は今だに自信がない…。

2013-03-15 02:49:27
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

だれかこれの理由おしえて RT @frsyuki: @tagomoris rubyのsyswriteですが、2GBは書いてくれないですねぇ。https://t.co/HH3YBDQHT5

2013-03-15 03:53:09
成瀬 @nalsh

@kosaki55tea @frsyuki @tagomoris ぱっと思いつくのは32bit linuxだからですけど、まさかそんなことはないですよね

2013-03-15 03:55:24
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

@nalsh @frsyuki @tagomoris 32bitでも2GBは書けるべきなのでは?という疑問だったんですが、書けないもん?

2013-03-15 03:56:06
成瀬 @nalsh

@kosaki55tea @frsyuki @tagomoris CRubyのStringやArrayの最大長などがlongのサイズに依存しているという非常に遺憾な仕様がありまして、現代では 32bit Unixはもちろん、msin64で泣けることになっております

2013-03-15 03:58:23
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

@nalsh @frsyuki @tagomoris longのサイズより4kぐらい小さいのはRubyがなんか中でやってるってこと?

2013-03-15 04:00:33
Sadayuki Furuhashi @frsyuki

@nalsh @kosaki55tea 実行したのは ruby 1.9.3p327 (2012-11-10 revision 37606) [x86_64-linux] です。

2013-03-15 04:00:36
成瀬 @nalsh

@nalsh @kosaki55tea @frsyuki @tagomoris 修正しようにも、CRubyのソースコードで関係あるlongを丁寧に書き換えることはもちろん、C拡張ライブラリのABI互換性・ソースコード互換性を派手にぶちこわすことになるのでなかなか……

2013-03-15 04:00:41
成瀬 @nalsh

@kosaki55tea @frsyuki @tagomoris いやぁ、単にわたしの32bitだからって推測が間違っていて別の理由なんでしょう

2013-03-15 04:01:41
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

@nalsh @frsyuki @tagomoris よく考えたらオレ、コミッタなんだから自分で知れべれるんだった。ちょっとマテ

2013-03-15 04:02:55
成瀬 @nalsh

@kosaki55tea @frsyuki @tagomoris コミッタじゃなくたってgrepでわかる範囲じゃろ。で、longとsize_tにしか依存してないのでCRuby無罪かなぁ

2013-03-15 04:04:27
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

@kosaki55tea @frsyuki @nalsh @tagomoris そして仮想マシンのメモリが少なすぎて実行できないという罠

2013-03-15 04:06:14
Sadayuki Furuhashi @frsyuki

誰かがちゃぴん先生にメモリを

2013-03-15 04:07:01
小崎 資広 (KOSAKI Motohiro) @kosaki55tea

@kosaki55tea @frsyuki @nalsh @tagomoris あ、できた。straceの結果、rubyは2GBのwriteをするが、カーネルが拒否ってるな。でrubyのsys writeの仕様

2013-03-15 04:11:30