old_thread_select.patch

Motohiro KOSAKI, 09/12/2011 02:27 AM

Download (3.09 KB)

View differences:

thread.c (working copy)
2395 2395
    memcpy(dst->fdset, src, size);
2396 2396
}
2397 2397

  
2398
static void
2399
rb_fd_rcopy(fd_set *dst, rb_fdset_t *src)
2400
{
2401
    size_t size = howmany(rb_fd_max(src), NFDBITS) * sizeof(fd_mask);
2402

  
2403
    if (size > sizeof(fd_set)) {
2404
	rb_raise(rb_eArgError, "too large fdsets");
2405
    }
2406
    memcpy(dst, rb_fd_ptr(src), sizeof(fd_set));
2407
}
2408

  
2398 2409
void
2399 2410
rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src)
2400 2411
{
......
2453 2464
    rb_fd_dup(dst, src);
2454 2465
}
2455 2466

  
2467
static void
2468
rb_fd_rcopy(fd_set *dst, rb_fdset_t *src)
2469
{
2470
    int max = rb_fd_max(src);
2471

  
2472
    if (max > FD_SETSIZE) {
2473
	rb_raise(rb_eArgError, "too large fdsets");
2474
    }
2475

  
2476
    memcpy(dst->fd_array, src->fdset->fd_array, max);
2477
    dst->fd_count = max;
2478
}
2479

  
2456 2480
void
2457 2481
rb_fd_term(rb_fdset_t *set)
2458 2482
{
......
2489 2513
#define FD_CLR(i, f)	rb_fd_clr((i), (f))
2490 2514
#define FD_ISSET(i, f)	rb_fd_isset((i), (f))
2491 2515

  
2516
#else
2517
#define rb_fd_rcopy(d, s) (*(d) = *(s))
2492 2518
#endif
2493 2519

  
2494 2520
#if defined(__CYGWIN__)
......
2710 2736

  
2711 2737
    retval = rb_thread_fd_select(max, rfds, wfds, efds, timeout);
2712 2738

  
2713
    if (rfds)
2739
    if (rfds) {
2740
	rb_fd_rcopy(read, rfds);
2714 2741
	rb_fd_term(rfds);
2715
    if (wfds)
2742
    }
2743
    if (wfds) {
2744
	rb_fd_rcopy(write, wfds);
2716 2745
	rb_fd_term(wfds);
2717
    if (efds)
2746
    }
2747
    if (efds) {
2748
	rb_fd_rcopy(except, efds);
2718 2749
	rb_fd_term(efds);
2750
    }
2719 2751

  
2720 2752
    return retval;
2721 2753
}
ext/-test-/old_thread_select/old_thread_select.c (working copy)
25 25
    return fds;
26 26
}
27 27

  
28
static void fdset2array(VALUE dst, fd_set *fds, int max)
29
{
30
    int i;
31

  
32
    rb_ary_clear(dst);
33

  
34
    for (i = 0; i < max; i++) {
35
	if (FD_ISSET(i, fds))
36
	    rb_ary_push(dst, INT2NUM(i));
37
    }
38
}
39

  
28 40
static VALUE
29 41
old_thread_select(VALUE klass, VALUE r, VALUE w, VALUE e, VALUE timeout)
30 42
{
......
45 57
    rc = rb_thread_select(max, rp, wp, ep, tvp);
46 58
    if (rc == -1)
47 59
	rb_sys_fail("rb_wait_for_single_fd");
60

  
61
    if (rp)
62
	fdset2array(r, &rfds, max);
63
    if (wp)
64
	fdset2array(w, &wfds, max);
65
    if (ep)
66
	fdset2array(e, &efds, max);
48 67
    return INT2NUM(rc);
49 68
}
50 69

  
test/-ext-/old_thread_select/test_old_thread_select.rb (working copy)
34 34
    end
35 35
  end
36 36

  
37
  def test_old_select_false_positive
38
    bug5306 = '[ruby-core:39435]'
39
    with_pipe do |r2, w2|
40
      with_pipe do |r, w|
41
        t0 = Time.now
42
        w.syswrite '.'
43
        rfds = [ r.fileno, r2.fileno ]
44
        rc = IO.old_thread_select(rfds, nil, nil, nil)
45
        assert_equal [ r.fileno ], rfds, bug5306
46
        assert_equal 1, rc, bug5306
47
      end
48
    end
49
  end
50

  
37 51
  def test_old_select_read_write_check
38 52
    with_pipe do |r, w|
39 53
      w.syswrite('.')