Backport #6352 » fix_em_segv2.patch
ext/-test-/win32/fd_setsize/depend | ||
---|---|---|
fd_setsize.o: $(top_srcdir)/win32/win32.c \
|
||
$(hdrdir)/ruby/ruby.h
|
ext/-test-/win32/fd_setsize/extconf.rb | ||
---|---|---|
if $mingw or $mswin
|
||
create_makefile("-test-/win32/fd_setsize")
|
||
end
|
ext/-test-/win32/fd_setsize/fd_setsize.c | ||
---|---|---|
#undef FD_SETSIZE
|
||
/* redefine smaller size then default 64 */
|
||
#define FD_SETSIZE 32
|
||
#include <ruby.h>
|
||
static VALUE
|
||
test_select(VALUE self)
|
||
{
|
||
int sd = socket(AF_INET, SOCK_DGRAM, 0);
|
||
struct timeval zero;
|
||
fd_set read;
|
||
fd_set write;
|
||
fd_set error;
|
||
zero.tv_sec = 0;
|
||
zero.tv_usec = 0;
|
||
FD_ZERO(&read);
|
||
FD_ZERO(&write);
|
||
FD_ZERO(&error);
|
||
FD_SET(sd, &read);
|
||
FD_SET(sd, &write);
|
||
FD_SET(sd, &error);
|
||
select(sd+1, &read, &write, &error, &zero);
|
||
return Qtrue;
|
||
}
|
||
static VALUE
|
||
test_fdset(VALUE self)
|
||
{
|
||
int i;
|
||
fd_set set;
|
||
FD_ZERO(&set);
|
||
for (i = 0; i < FD_SETSIZE * 2; i++) {
|
||
int sd = socket(AF_INET, SOCK_DGRAM, 0);
|
||
FD_SET(sd, &set);
|
||
if (set.fd_count > FD_SETSIZE) {
|
||
return Qfalse;
|
||
}
|
||
}
|
||
return Qtrue;
|
||
}
|
||
void
|
||
Init_fd_setsize(void)
|
||
{
|
||
VALUE m = rb_define_module_under(rb_define_module("Bug"), "Win32");
|
||
rb_define_module_function(m, "test_select", test_select, 0);
|
||
rb_define_module_function(m, "test_fdset", test_fdset, 0);
|
||
}
|
include/ruby/win32.h | ||
---|---|---|
#define O_NONBLOCK 1
|
||
#undef FD_SET
|
||
#define FD_SET(f, s) rb_w32_fdset(f, s)
|
||
#define FD_SET(fd, set) do {\
|
||
unsigned int i;\
|
||
SOCKET s = _get_osfhandle(fd);\
|
||
\
|
||
for (i = 0; i < (set)->fd_count; i++) {\
|
||
if ((set)->fd_array[i] == s) {\
|
||
break;\
|
||
}\
|
||
}\
|
||
if (i == (set)->fd_count) {\
|
||
if ((set)->fd_count < FD_SETSIZE) {\
|
||
(set)->fd_array[i] = s;\
|
||
(set)->fd_count++;\
|
||
}\
|
||
}\
|
||
} while(0)
|
||
#undef FD_CLR
|
||
#define FD_CLR(f, s) rb_w32_fdclr(f, s)
|
test/-ext-/win32/test_fd_setsize.rb | ||
---|---|---|
require 'test/unit'
|
||
require_relative '../../ruby/envutil'
|
||
module Bug
|
||
module Win32
|
||
class TestFdSetSize < Test::Unit::TestCase
|
||
def test_select_with_unmatched_fd_setsize
|
||
bug6532 = '[ruby-core:44588]'
|
||
assert_in_out_err([], <<-INPUT, %w(:ok), [], bug6532)
|
||
require '-test-/win32/fd_setsize'
|
||
Bug::Win32.test_select
|
||
p :ok
|
||
INPUT
|
||
end
|
||
def test_fdset_with_unmatched_fd_setsize
|
||
bug6532 = '[ruby-core:44588]'
|
||
assert_in_out_err([], <<-INPUT, %w(:ok), [], bug6532)
|
||
require '-test-/win32/fd_setsize'
|
||
p :ok if Bug::Win32.test_fdset
|
||
INPUT
|
||
end
|
||
end
|
||
end
|
||
end if /mswin|mingw/ =~ RUBY_PLATFORM
|
win32/win32.c | ||
---|---|---|
return -1;
|
||
}
|
||
#undef FD_SET
|
||
void
|
||
rb_w32_fdset(int fd, fd_set *set)
|
||
{
|
||
unsigned int i;
|
||
SOCKET s = TO_SOCKET(fd);
|
||
for (i = 0; i < set->fd_count; i++) {
|
||
if (set->fd_array[i] == s) {
|
||
return;
|
||
}
|
||
}
|
||
if (i == set->fd_count) {
|
||
if (set->fd_count < FD_SETSIZE) {
|
||
set->fd_array[i] = s;
|
||
set->fd_count++;
|
||
}
|
||
}
|
||
FD_SET(fd, set);
|
||
}
|
||
#undef FD_CLR
|
||
... | ... | |
fd_set orig_rd;
|
||
fd_set orig_wr;
|
||
fd_set orig_ex;
|
||
if (rd) orig_rd = *rd;
|
||
if (wr) orig_wr = *wr;
|
||
if (ex) orig_ex = *ex;
|
||
FD_ZERO(&orig_rd);
|
||
FD_ZERO(&orig_wr);
|
||
FD_ZERO(&orig_ex);
|
||
if (rd) copy_fd(&orig_rd, rd);
|
||
if (wr) copy_fd(&orig_wr, wr);
|
||
if (ex) copy_fd(&orig_ex, ex);
|
||
r = do_select(nfds, rd, wr, ex, &zero); // polling
|
||
if (r != 0) break; // signaled or error
|
||
if (rd) *rd = orig_rd;
|
||
if (wr) *wr = orig_wr;
|
||
if (ex) *ex = orig_ex;
|
||
if (rd) copy_fd(rd, &orig_rd);
|
||
if (wr) copy_fd(wr, &orig_wr);
|
||
if (ex) copy_fd(ex, &orig_ex);
|
||
if (timeout) {
|
||
struct timeval now;
|
- « Previous
- 1
- 2
- 3
- Next »