[#24112] ruby/tk crashes on bcc32 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>

山本です。原因を追求してたのですが、力尽きました。

19 messages 2004/08/18
[#24127] Re: ruby/tk crashes on bcc32 — Hidetoshi NAGAI <nagai@...> 2004/08/19

永井@知能.九工大です.

[#24131] Re: ruby/tk crashes on bcc32 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2004/08/19

山本です。

[#24135] Re: ruby/tk crashes on bcc32 — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp> 2004/08/19

山本です。試行錯誤の結果、これで落ちなくなりました。

[ruby-dev:24075] Re: SSLSocket#sysread block a whole process.

From: GOTOU Yuuzou <gotoyuzo@...>
Date: 2004-08-14 04:24:07 UTC
List: ruby-dev #24075
In message <87llgiscks.fsf@serein.a02.aist.go.jp>,
 `Tanaka Akira <akr@m17n.org>' wrote:
> [ruby-dev:24072] で気になって ossl_ssl_read を眺めて気がついたのですが、
> OpenSSL::SSL::SSLSocket#sysread でブロックすると、プロセス全体がブロッ
> クして、他のスレッドに制御が移らないようです。
> 
> % ruby -rsocket -ropenssl -e '
> Thread.new { loop { p "xxx"; sleep 1 } }
> s = TCPSocket.open("javacc.dev.java.net", 443)
> OpenSSL::SSL::SSLSocket.new(s).sysread(1)  
> '
> "xxx"
> 
> これはよろしくないんじゃないでしょうか。

こんな感じでどうでしょうか。
SSL_readを呼ぶ方はrb_thread_wait_fdを呼んだところで、到着し
ているデータが中途半端だとブロックするのかもしれないのですが。

-- 
ごとうゆうぞう

Index: ext/openssl/ossl_ssl.c
===================================================================
RCS file: /var/cvs/src/ruby/ext/openssl/ossl_ssl.c,v
retrieving revision 1.14
diff -u -p -F^[^A-Za-z0-9_+-]*\(class\|module\|def\)[^A-Za-z0-9_+-] -r1.14 ossl_ssl.c
--- ext/openssl/ossl_ssl.c	26 May 2004 18:11:29 -0000	1.14
+++ ext/openssl/ossl_ssl.c	14 Aug 2004 04:17:26 -0000
@@ -492,6 +492,7 @@ ossl_ssl_read(int argc, VALUE *argv, VAL
     OpenFile *fptr;
 
     Data_Get_Struct(self, SSL, ssl);
+    GetOpenFile(ossl_ssl_get_io(self), fptr);
     rb_scan_args(argc, argv, "11", &len, &str);
     ilen = NUM2INT(len);
     if(NIL_P(str)) str = rb_str_new(0, ilen);
@@ -500,37 +501,34 @@ ossl_ssl_read(int argc, VALUE *argv, VAL
         rb_str_modify(str);
         rb_str_resize(str, ilen);
     }
+    if(ilen == 0) return str;
 
     if (ssl) {
+	if(SSL_pending(ssl) <= 0)
+	    rb_thread_wait_fd(fileno(fptr->f));
 	for (;;){
 	    nread = SSL_read(ssl, RSTRING(str)->ptr, RSTRING(str)->len);
 	    switch(SSL_get_error(ssl, nread)){
 	    case SSL_ERROR_NONE:
 		goto end;
 	    case SSL_ERROR_ZERO_RETURN:
-		ossl_raise(rb_eEOFError, "End of file reached");
+		rb_eof_error();
 	    case SSL_ERROR_WANT_WRITE:
 	    case SSL_ERROR_WANT_READ:
 		rb_thread_schedule();
 		continue;
+	    case SSL_ERROR_SYSCALL:
+		if(ERR_peek_error() == 0 && nread == 0) rb_eof_error();
+		ossl_raise(eSSLError, "SSL_read: %s", strerror(errno));
 	    default:
 		ossl_raise(eSSLError, "SSL_read:");
 	    }
         }
     }
     else {
+        ID id_sysread = rb_intern("sysread");
         rb_warning("SSL session is not started yet.");
-        GetOpenFile(ossl_ssl_get_io(self), fptr);
-        rb_io_check_readable(fptr);
-        TRAP_BEG;
-        nread = read(fileno(fptr->f), RSTRING(str)->ptr, RSTRING(str)->len);
-        TRAP_END;
-	if (nread == 0) {
-	    ossl_raise(rb_eEOFError, "End of file reached");
-	}
-        if(nread < 0) {
-            ossl_raise(eSSLError, "read:%s", strerror(errno));
-        }
+        return rb_funcall(ossl_ssl_get_io(self), id_sysread, 2, len, str);
     }
 
   end:
@@ -568,14 +566,9 @@ ossl_ssl_write(VALUE self, VALUE str)
         }
     }
     else {
+        ID id_syswrite = rb_intern("syswrite");
         rb_warning("SSL session is not started yet.");
-        GetOpenFile(ossl_ssl_get_io(self), fptr);
-        rb_io_check_writable(fptr);
-        fp = GetWriteFile(fptr);
-        nwrite = write(fileno(fp), RSTRING(str)->ptr, RSTRING(str)->len);
-        if (nwrite < 0) {
-            ossl_raise(eSSLError, "write:%s", strerror(errno));
-        }
+        return rb_funcall(ossl_ssl_get_io(self), id_syswrite, 1, str);
     }
 
   end:

In This Thread

Prev Next