Forum: Ruby-core Windows sockets and CRT fds

Posted by Greg Hazel (ghazel)
on 2011-01-14 04:34
(Received via mailing list)
Hi,

I was recently debugging a hang on the mysql2 gem. The cause turned
out to be that the socket file descriptor from libmysql was being
passed in to rb_thread_select():
https://github.com/brianmario/mysql2/blob/8c0c350c...

This worked fine on linux, but on Windows rb_thread_select would never
return. The rb_thread_select function expects CRT fds (made with
_open_osfhandle()). Ruby win32 code goes to great lengths to redefine
socket(), FD_SET, FD_ISSET, and a pile of other functions, so that
extensions like EventMachine create and work with the CRT fds instead
of the SOCKET handles transparently. However in cases like like mysql2
and curb (which uses libcurl), the socket is created by an external
library, and the handle is the SOCKET, not the CRT fd. Here's the curb
case: 
https://github.com/taf2/curb/blob/5f223a8f2e0de3e6...

My question is; why does Ruby go through all this trouble on Windows?
Why not pass around and work with SOCKET handles instead?

-Greg
Posted by U.Nakamura (Guest)
on 2011-01-14 05:04
(Received via mailing list)
Hello,

In message "[ruby-core:34483] Windows sockets and CRT fds"
    on Jan.14,2011 12:27:48, <ghazel@gmail.com> wrote:
> My question is; why does Ruby go through all this trouble on Windows?
> Why not pass around and work with SOCKET handles instead?

Because, if do so, we must rewrite all ruby core functions and
extensions which expect that socket is a kind of file descriptor.

About mysql2 gem, it should know how MySQL treats Windows SOCKETs
and how Ruby treats them.
And it should fill in the gap.  It's the work of wrapper library.


Regards,
Posted by Greg Hazel (ghazel)
on 2011-01-14 05:37
(Received via mailing list)
On Thu, Jan 13, 2011 at 8:03 PM, U.Nakamura <usa@garbagecollect.jp> 
wrote:
> In message "[ruby-core:34483] Windows sockets and CRT fds"
>    on Jan.14,2011 12:27:48, <ghazel@gmail.com> wrote:
>> My question is; why does Ruby go through all this trouble on Windows?
>> Why not pass around and work with SOCKET handles instead?
>
> Because, if do so, we must rewrite all ruby core functions and
> extensions which expect that socket is a kind of file descriptor.

I understand it would have to be rewritten to change it, but why was
it written that way to begin with? Aside from the effort to change it,
is there anything lost or gained by switching?

> About mysql2 gem, it should know how MySQL treats Windows SOCKETs
> and how Ruby treats them.
> And it should fill in the gap.  It's the work of wrapper library.

Unfortunately this is quite difficult. Libraries like libmysql create
and destroy their own sockets, so it is rarely possible to create and
destroy a CRT fd at the same time. Creating a CRT fd when you need it
(to pass to rb_thread_select) is fine, but closing it afterwards
closes the underlying socket at well. Tracking the associated CRT fds
and trying to close them when it's safe is a lot of effort, and maybe
not possible if you don't get a destroy event.

More importantly: no one has done it correctly. Every author of a ruby
extension I can find has completely missed this subtlety of Ruby's
Win32 code - since just treating linux fds as fds with
rb_select_thread works fine.

So, I think by switching to SOCKET handles right now, more extensions
would start working on Windows than do today. I have yet to find one
which would be broken by the switch.

-Greg
Posted by U.Nakamura (Guest)
on 2011-01-14 07:06
(Received via mailing list)
Hello,

In message "[ruby-core:34485] Re: Windows sockets and CRT fds"
    on Jan.14,2011 13:35:42, <ghazel@gmail.com> wrote:
> I understand it would have to be rewritten to change it, but why was
> it written that way to begin with? Aside from the effort to change it,
> is there anything lost or gained by switching?

Q: why was it written that way to begin with?
A: Sorry, I don't know.  I guess that the author might not want
   to put many #ifdef-s into ruby core source.

Q: Aside from the effort to change it, is there anything lost or
   gained by switching?
A: Currently the programmer of an extension library doesn't need
   to know about Windows if the extension library is not linked
   to outer libraries.  After the switching, he must write two
   code for Unix and Windows.  Of course, if the extension library
   depends on outer libraries which treat Unix and Windows by
   different way, his time will decrease because of omitting
   the code for ruby's faked FD.


> So, I think by switching to SOCKET handles right now, more extensions
> would start working on Windows than do today. I have yet to find one
> which would be broken by the switch.

Anyway, the patch is welcomed.
If the patch is better enough than current, it will be applied
naturally. (However, the timing is not certain because we must
take care of ABI compatiblity.)


Regards,
Posted by Greg Hazel (ghazel)
on 2011-01-14 23:17
(Received via mailing list)
On Thu, Jan 13, 2011 at 10:03 PM, U.Nakamura <usa@garbagecollect.jp> 
wrote:
>   to put many #ifdef-s into ruby core source.
win32.c and win32.h have a ton of ifdefs in them. What I'm proposing
would remove many of them, and not add any to the rest of Ruby code.
Who is the author of the _open_osfhandle code?

> Q: Aside from the effort to change it, is there anything lost or
>   gained by switching?
> A: Currently the programmer of an extension library doesn't need
>   to know about Windows if the extension library is not linked
>   to outer libraries.  After the switching, he must write two
>   code for Unix and Windows.  Of course, if the extension library
>   depends on outer libraries which treat Unix and Windows by
>   different way, his time will decrease because of omitting
>   the code for ruby's faked FD.

I'm not sure which parts you're saying need to be rewritten for Unix
and Windows. Currently there needs to be different code for Unix and
Windows, because a socket handle you might come across on Windows has
to be adapted to the sort of fd that ruby uses. After the hypothetical
switch to using regular Windows sockets in Ruby, you could take a
socket handle from anywhere and select on it in Ruby and have no
Windows specific code (except inside of Ruby). So, I only see it
reducing the amount of platform specific code (and bugs) in
extensions.

-Greg
Posted by Stephen Bannasch (Guest)
on 2011-01-15 01:48
(Received via mailing list)
At 6:49 AM +0900 1/15/11, ghazel@gmail.com wrote:
>> A: Sorry, I don't know.  I guess that the author might not want
>>   to put many #ifdef-s into ruby core source.
>
>win32.c and win32.h have a ton of ifdefs in them. What I'm proposing
>would remove many of them, and not add any to the rest of Ruby code.
>Who is the author of the _open_osfhandle code?

[Sometimes I find playing with git a bit like a crossword puzzle ... 
there's almost always some way to do what I want ...]

Here's a summary of all the locations in win32/win32.c that reference 
open_osfhandle.

The first part of each listing uses git blame to list the last author 
who changed that line.
This section also includes the 3 lines before and after the reference. 
Each of these lines starts with the first 8 characters of the git commit 
SHA of thfollowed by the author, the date, line number and then the line 
itself.

The second part displays the commit message for the fourth line where 
open_osfhandle is referenced. The subversion revisionnumber is on the 
line in this section starting with  git-svn-id.

[ruby-git (trunk)]$ git grep -nh  open_osfhandle win32/win32.c | cut -d 
: -f 1 | xargs -n 1 ruby -e 'linenum=ARGV[0].to_i;blame=`git blame -c -L 
#{linenum-3},+7 win32/win32.c`; puts"\n\n#{blame}\n"; puts `git log -1 
#{blame.split("\n")[3][0..7]}`'

d35fdf33  (       usa  2010-09-02 00:02:52 +0000  66)static 
structChildRecord *CreateChild(const WCHAR *, const WCHAR *, 
SECURITY_ATTRIBUTES *, HANDLE, HANDLE, HANDLE);
b1469c13  (       usa  2004-06-09 03:47:08 +0000  67)static int 
has_redirection(const char *);
bb022bed  (       usa  2007-02-23 09:33:53 +0000  68)int 
rb_w32_wait_events(HANDLE *events, int num, DWORD timeout);
1aa54c6d  (       usa  2007-06-27 11:47:53 +0000  69)static int 
rb_w32_open_osfhandle(intptr_t osfhandle, int flags);
a8209ffc  (    wanabe  2010-04-30 21:45:33 +0000  70)static int 
wstati64(const WCHAR *path, struct stati64*st);
2c01a07b  (      nobu  2010-05-08 03:25:17 +0000  71)VALUE 
rb_w32_conv_from_wchar(const WCHAR *wstr, rb_encoding *enc);
edf2e9b7  (      matz  1999-01-20 04:45:32 +0000  72)

commit 1aa54c6db6a10bf671a80eddf93630fbbea4f810
Author: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date:   Wed Jun 27 11:47:53 2007 +0000

     * include/ruby/win32.h, win32/Makefile.sub, win32/configure.bat,
       win32/mkexports.rb, win32/setup.mak, win32/win32.c: import
       x64-mswin64 port.



    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12635 
b2dd03c8-39d4-4d8f-98ff-823fe69b080e


65a51625  (      matz  1999-08-13 05:45:20 +0000  2056)#define FTEXT 
0x80  /* file handle is in text mode */
65a51625  (      matz  1999-08-13 05:45:20 +0000  2057)
6d53b692  (      eban  2000-05-13 16:13:31 +0000  2058)static int
1aa54c6d  (       usa  2007-06-27 11:47:53 +0000 
2059)rb_w32_open_osfhandle(intptr_t osfhandle, int flags)
65a51625  (      matz  1999-08-13 05:45:20 +0000  2060){
65a51625  (      matz  1999-08-13 05:45:20 +0000  2061)    int fh;
65a51625  (      matz  1999-08-13 05:45:20 +0000  2062)    char 
fileflags;    /* _osfile flags */

commit 1aa54c6db6a10bf671a80eddf93630fbbea4f810
Author: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date:   Wed Jun 27 11:47:53 2007 +0000

     * include/ruby/win32.h, win32/Makefile.sub, win32/configure.bat,
       win32/mkexports.rb, win32/setup.mak, win32/win32.c: import
       x64-mswin64 port.



    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12635 
b2dd03c8-39d4-4d8f-98ff-823fe69b080e


3d6fde33  (      matz  2000-02-18 06:59:36 +0000  2076)
7345d0ef  (      nobu  2002-09-29 09:31:58 +0000  2077)    /* attempt to 
allocate a C Runtimefile handle */
7345d0ef  (      nobu  2002-09-29 09:31:58 +0000  2078)    hF 
=CreateFile("NUL", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);
150b4efa  (      nobu  2010-10-12 14:58:23 +0000  2079)    fh 
=_open_osfhandle((intptr_t)hF, 0);
7345d0ef  (      nobu  2002-09-29 09:31:58 +0000  2080) 
CloseHandle(hF);
7345d0ef  (      nobu  2002-09-29 09:31:58 +0000  2081)    if (fh == -1) 
{
7345d0ef  (      nobu  2002-09-29 09:31:58 +0000  2082)  errno = EMFILE; 
/* too many openfiles */

commit 150b4efa5510d77fdde7b9692b3c391fbde6ac19
Author: nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date:   Tue Oct 12 14:58:23 2010 +0000

    * win32/win32.c (rb_w32_open_osfhandle, rb_w32_wopen, rb_w32_pipe):
      use uintptr_t instead of long for win64.

    * win32/win32.c (socketpair_internal): suppress warnings.

    * win32/win32.c (ftruncate): use HANDLE instead of long for win64.

    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29467 
b2dd03c8-39d4-4d8f-98ff-823fe69b080e


65a51625  (      matz  1999-08-13 05:45:20 +0000  2141)
160bfa5b  (     ocean  2005-01-06 11:05:31 +0000  2142)#ifdef 
__BORLANDC__
160bfa5b  (     ocean  2005-01-06 11:05:31 +0000  2143)static int
92cad430  (      nobu  2007-07-21 08:32:34 +0000 
2144)rb_w32_open_osfhandle(intptr_t osfhandle, int flags)
160bfa5b  (     ocean  2005-01-06 11:05:31 +0000  2145){
160bfa5b  (     ocean  2005-01-06 11:05:31 +0000  2146)    int fd = 
_open_osfhandle(osfhandle, flags);
160bfa5b  (     ocean  2005-01-06 11:05:31 +0000  2147)    if (fd == -1) 
{

commit 92cad4305b1751fcea0bcfe1386e8f8cba265167
Author: nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date:   Sat Jul 21 08:32:34 2007 +0000

    * bcc32/{Makefile.sub,configure.bat,setup.mak: configure_args
      support.

    * bcc32/setup.mak: check runtime version.

    * win32/win32.c (rb_w32_open_osfhandle): prototype has changed
      in bcc 5.82.


    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12831 
b2dd03c8-39d4-4d8f-98ff-823fe69b080e


160bfa5b  (     ocean  2005-01-06 11:05:31 +0000  2143)static int
92cad430  (      nobu  2007-07-21 08:32:34 +0000 
2144)rb_w32_open_osfhandle(intptr_t osfhandle, int flags)
160bfa5b  (     ocean  2005-01-06 11:05:31 +0000  2145){
160bfa5b  (     ocean  2005-01-06 11:05:31 +0000  2146)    int fd = 
_open_osfhandle(osfhandle, flags);
160bfa5b  (     ocean  2005-01-06 11:05:31 +0000  2147)    if (fd == -1) 
{
160bfa5b  (     ocean  2005-01-06 11:05:31 +0000  2148)  errno = EMFILE; 
/* too many openfiles */
160bfa5b  (     ocean  2005-01-06 11:05:31 +0000  2149)  _doserrno = 0L; 
/* not an OS error */

commit 160bfa5befa7de9a8675afe4efb05882e5020301
Author: ocean <ocean@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date:   Thu Jan 6 11:05:31 2005 +0000

    * win32/win32.c (rb_w32_close): didn't close socket handle.

    * win32/win32.c (rb_w32_open_osfhandle): bcc32's _open_osfhandle
      never set EMFILE.


    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7737 
b2dd03c8-39d4-4d8f-98ff-823fe69b080e


edf2e9b7  (      matz  1999-01-20 04:45:32 +0000  2687)    }
62280094  (       usa  2002-09-28 21:39:57 +0000  2688) 
RUBY_CRITICAL({
d544a3d6  (       usa  2008-11-11 08:54:07 +0000  2689)  HANDLE h = 
CreateFile("NUL", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);
d544a3d6  (       usa  2008-11-11 08:54:07 +0000  2690)  fd = 
rb_w32_open_osfhandle((intptr_t)h, O_RDWR|O_BINARY|O_NOINHERIT);
d544a3d6  (       usa  2008-11-11 08:54:07 +0000  2691)  if (fd != -1) {
d544a3d6  (       usa  2008-11-11 08:54:07 +0000  2692)      r = 
accept(TO_SOCKET(s), addr, addrlen);
d544a3d6  (       usa  2008-11-11 08:54:07 +0000  2693)     if (r != 
INVALID_SOCKET) {

commit d544a3d6c721b435151a74cb00aa32142a284097
Author: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date:   Tue Nov 11 08:54:07 2008 +0000

     * win32/win32.c (rb_w32_accept): secure fd before accept because if
       error causes in securing, cannot restore the state of accepted
       socket.
       fixed [ruby-core:19728]



    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20189 
b2dd03c8-39d4-4d8f-98ff-823fe69b080e


7345d0ef  (      nobu  2002-09-29 09:31:58 +0000  3214)      fd = -1;
7345d0ef  (      nobu  2002-09-2909:31:58 +0000  3215)  }
7345d0ef  (      nobu  2002-09-29 09:31:58 +0000  3216)  else {
4532c0d8  (       usa  2008-07-11 07:18:29 +0000  3217)      fd = 
rb_w32_open_osfhandle(s, O_RDWR|O_BINARY|O_NOINHERIT);
84658471  (       usa  2008-07-24 07:33:00 +0000  3218)      if (fd != 
-1)
84658471  (       usa  2008-07-24 07:33:00 +0000  3219) 
st_insert(socklist, (st_data_t)s, (st_data_t)0);
84658471  (       usa  2008-07-24 07:33:00 +0000  3220)      else

commit 4532c0d81ef7aeb6d75d7bbe099682ef90165e29
Author: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date:   Fri Jul 11 07:18:29 2008 +0000

     * win32/win32.c (rb_w32_accept, rb_w32_socket, rb_w32_socketpair):
       prohibit inheritance of sockets, too. [experimental]



    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18024 
b2dd03c8-39d4-4d8f-98ff-823fe69b080e


c3ce319d  (       usa  2004-12-07 15:47:59 +0000  3440)
c3ce319d  (       usa  2004-12-07 15:47:59 +0000  3441)    if 
(socketpair_internal(af, type, protocol, pair) < 0)
c3ce319d  (       usa  2004-12-07 15:47:59 +0000  3442)  return -1;
4532c0d8  (       usa  2008-07-11 07:18:29 +0000  3443)    sv[0] = 
rb_w32_open_osfhandle(pair[0], O_RDWR|O_BINARY|O_NOINHERIT);
84658471  (       usa  2008-07-24 07:33:00 +0000  3444)    if (sv[0] == 
-1) {
84658471  (       usa  2008-07-24 07:33:00 +0000  3445) 
closesocket(pair[0]);
84658471  (       usa  2008-07-24 07:33:00 +0000  3446) 
closesocket(pair[1]);

commit 4532c0d81ef7aeb6d75d7bbe099682ef90165e29
Author: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date:   Fri Jul 11 07:18:29 2008 +0000

     * win32/win32.c (rb_w32_accept, rb_w32_socket, rb_w32_socketpair):
       prohibit inheritance of sockets, too. [experimental]



    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18024 
b2dd03c8-39d4-4d8f-98ff-823fe69b080e


84658471  (       usa  2008-07-24 07:33:00 +0000  3446) 
closesocket(pair[1]);
84658471  (       usa  2008-07-24 07:33:00 +0000  3447)  return -1;
84658471  (       usa  2008-07-24 07:33:00 +0000  3448)    }
4532c0d8  (       usa  2008-07-11 07:18:29 +0000  3449)    sv[1] = 
rb_w32_open_osfhandle(pair[1], O_RDWR|O_BINARY|O_NOINHERIT);
84658471  (       usa  2008-07-24 07:33:00 +0000  3450)    if (sv[1] == 
-1) {
84658471  (       usa  2008-07-24 07:33:00 +0000  3451) 
rb_w32_close(sv[0]);
84658471  (       usa  2008-07-24 07:33:00 +0000  3452) 
closesocket(pair[1]);

commit 4532c0d81ef7aeb6d75d7bbe099682ef90165e29
Author: usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date:   Fri Jul 11 07:18:29 2008 +0000

     * win32/win32.c (rb_w32_accept, rb_w32_socket, rb_w32_socketpair):
       prohibit inheritance of sockets, too. [experimental]



    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18024 
b2dd03c8-39d4-4d8f-98ff-823fe69b080e


3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4829)    /* allocate a 
C Runtime file handle */
3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4830) 
RUBY_CRITICAL({
3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4831)  h = 
CreateFile("NUL", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);
150b4efa  (      nobu  2010-10-12 14:58:23 +0000  4832)  fd = 
_open_osfhandle((intptr_t)h, 0);
3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4833)  CloseHandle(h);
3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4834)    });
3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4835)    if (fd == -1) 
{

commit 150b4efa5510d77fdde7b9692b3c391fbde6ac19
Author: nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date:   Tue Oct 12 14:58:23 2010 +0000

    * win32/win32.c (rb_w32_open_osfhandle, rb_w32_wopen, rb_w32_pipe):
      use uintptr_t instead of long for win64.

    * win32/win32.c (socketpair_internal): suppress warnings.

    * win32/win32.c (ftruncate): use HANDLE instead of long for win64.

    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29467 
b2dd03c8-39d4-4d8f-98ff-823fe69b080e


3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4948) 
RUBY_CRITICAL(do {
3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4949)  ret = 0;
3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4950)  h = 
CreateFile("NUL", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);
150b4efa  (      nobu  2010-10-12 14:58:23 +0000  4951)  fdRead = 
_open_osfhandle((intptr_t)h, 0);
3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4952)  CloseHandle(h);
3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4953)  if (fdRead == 
-1) {
3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4954)      errno = 
EMFILE;

commit 150b4efa5510d77fdde7b9692b3c391fbde6ac19
Author: nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date:   Tue Oct 12 14:58:23 2010 +0000

    * win32/win32.c (rb_w32_open_osfhandle, rb_w32_wopen, rb_w32_pipe):
      use uintptr_t instead of long for win64.

    * win32/win32.c (socketpair_internal): suppress warnings.

    * win32/win32.c (ftruncate): use HANDLE instead of long for win64.

    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29467 
b2dd03c8-39d4-4d8f-98ff-823fe69b080e


3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4968)
3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4969) 
RUBY_CRITICAL(do {
3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4970)  h = 
CreateFile("NUL", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);
150b4efa  (      nobu  2010-10-12 14:58:23 +0000  4971)  fdWrite = 
_open_osfhandle((intptr_t)h, 0);
3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4972)  CloseHandle(h);
3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4973)  if (fdWrite == 
-1) {
3c8dca55  (       usa  2008-08-28 12:46:58 +0000  4974)     errno = 
EMFILE;

commit 150b4efa5510d77fdde7b9692b3c391fbde6ac19
Author: nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date:   Tue Oct 12 14:58:23 2010 +0000

    * win32/win32.c (rb_w32_open_osfhandle, rb_w32_wopen, rb_w32_pipe):
      use uintptr_t instead of long for win64.

    * win32/win32.c (socketpair_internal): suppress warnings.

    * win32/win32.c (ftruncate): use HANDLE instead of long for win64.

    git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29467 
b2dd03c8-39d4-4d8f-98ff-823fe69b080e
[ruby-git (trunk)]$
Posted by Greg Hazel (ghazel)
on 2011-01-15 20:00
(Received via mailing list)
On Fri, Jan 14, 2011 at 4:47 PM, Stephen Bannasch
<stephen.bannasch@deanbrook.org> wrote:
>>> Q: why was it written that way to begin with?
>>> A: Sorry, I don't know.  I guess that the author might not want
>>>   to put many #ifdef-s into ruby core source.
>>
>>win32.c and win32.h have a ton of ifdefs in them. What I'm proposing
>>would remove many of them, and not add any to the rest of Ruby code.
>>Who is the author of the _open_osfhandle code?
>
> [Sometimes I find playing with git a bit like a crossword puzzle ... there's 
almost always some way to do what I want ...]
>
> Here's a summary of all the locations in win32/win32.c that reference 
open_osfhandle.

Thank you for encouraging me to dig. The use of _open_osfhandle I'm
referring to dates back to 2000-11-15 when it was added with this
helpful comment:

C:\ruby\win32>svn log -r 1040
------------------------------------------------------------------------
r1040 | matz | 2000-11-15 23:24:21 -0800 (Wed, 15 Nov 2000) | 2 lines

matz

------------------------------------------------------------------------

I believe, from reading the commit, that the intention was to
implement fddup. It seems according to this next commit though, that
fddup was removed and the need for it disappeared in ruby 1.7:

C:\ruby\win32>svn log -r 2916
------------------------------------------------------------------------
r2916 | nobu | 2002-10-01 08:26:39 -0700 (Tue, 01 Oct 2002) | 7 lines

        * ext/socket/socket.c (init_sock): no need for special 
finalizer,
          socket descriptor is no longer duplicated in 1.7.
          [ruby-talk:50732]

        * win32/win32.c, win32/win32.h (rb_w32_fddup, rb_w32_fdclose):
          delete.
Posted by U.Nakamura (Guest)
on 2011-01-17 01:51
(Received via mailing list)
Hello,

In message "[ruby-core:34509] Re: Windows sockets and CRT fds"
    on Jan.15,2011 06:49:55, <ghazel@gmail.com> wrote:
> Who is the author of the _open_osfhandle code?

"svn ann" will show you it.


> I'm not sure which parts you're saying need to be rewritten for Unix
> and Windows. Currently there needs to be different code for Unix and
> Windows, because a socket handle you might come across on Windows has
> to be adapted to the sort of fd that ruby uses. After the hypothetical
> switch to using regular Windows sockets in Ruby, you could take a
> socket handle from anywhere and select on it in Ruby and have no
> Windows specific code (except inside of Ruby). So, I only see it
> reducing the amount of platform specific code (and bugs) in
> extensions.

If you think so, could you show the patch that shows the concept?
Especially, I want know how about the main body of ruby, ext/socket,
and ext/openssl.


Regards,
Posted by Greg Hazel (ghazel)
on 2011-01-17 02:10
(Received via mailing list)
On Sun, Jan 16, 2011 at 4:51 PM, U.Nakamura <usa@garbagecollect.jp> 
wrote:
> If you think so, could you show the patch that shows the concept?
> Especially, I want know how about the main body of ruby, ext/socket,
> and ext/openssl.

Those will not change. It would only affect the Win32 code. If I make
a patch against 1.8.7, assuming everyone likes it, is there any hope
of it being accepted for 1.8.7 or 1.8.8?

The problem is even worse in Ruby 1.9. IS_SOCKET() checks whether the
handle is in an internal list or not, so the socket created by
libmysql will not appear to be a socket, and there is nothing the
extension writer can do to work around that since the list is not
exposed in any way.. Thankfully 1.9 has rb_thread_blocking_region so
the extension writer can use real select(), but there is no way to
write it to be compatible with both versions without an ifdef. I could
write a patch which fixes this for 1.9 as well, if the 1.8 patch is
accepted.

-Greg
Posted by Roger Pack (Guest)
on 2011-06-11 12:07
(Received via mailing list)
Attempt 2 (perhaps using quotation marks in my message caused it to
kill the spam scanner?)

> and curb (which uses libcurl), the socket is created by an external
> library, and the handle is the SOCKET, not the CRT fd.

So is there currently any known way to pass a (library's socket) into
select in a ruby extension in windows? I suppose one could just
surround a read call in a thread blocking region and get a similar
effect, they just couldn't do that for more than one socket per thread
I suppose...

ref: https://github.com/brianmario/mysql2/issues/142

Thanks!
-roger-
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.