0001-thread.c-rb_thread_select-mark-original-fd_sets-prop.patch

Eric Wong, 09/11/2011 03:12 PM

Download (4.08 KB)

View differences:

ext/-test-/old_thread_select/old_thread_select.c
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
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('.')
thread.c
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)) size = sizeof(fd_set);
2404
    memcpy(dst, rb_fd_ptr(src), size);
2405
}
2406

  
2398 2407
void
2399 2408
rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src)
2400 2409
{
......
2453 2462
    rb_fd_dup(dst, src);
2454 2463
}
2455 2464

  
2465
/* XXX completely untested */
2466
static void
2467
rb_fd_rcopy(fd_set *dst, rb_fdset_t *src)
2468
{
2469
	memcpy(dst->fd_array, src->fdset->fd_array,
2470
	       dst->fd_count * sizeof(dst->fd_array[0]);
2471
	dst->fd_count = src->fdset->fd_count;
2472
}
2473

  
2456 2474
void
2457 2475
rb_fd_term(rb_fdset_t *set)
2458 2476
{
......
2489 2507
#define FD_CLR(i, f)	rb_fd_clr((i), (f))
2490 2508
#define FD_ISSET(i, f)	rb_fd_isset((i), (f))
2491 2509

  
2510
#else
2511
#define rb_fd_rcopy(d, s) (*(d) = *(s))
2492 2512
#endif
2493 2513

  
2494 2514
#if defined(__CYGWIN__)
......
2710 2730

  
2711 2731
    retval = rb_thread_fd_select(max, rfds, wfds, efds, timeout);
2712 2732

  
2713
    if (rfds)
2733
    if (rfds) {
2734
	rb_fd_rcopy(read, rfds);
2714 2735
	rb_fd_term(rfds);
2715
    if (wfds)
2736
    }
2737
    if (wfds) {
2738
	rb_fd_rcopy(write, wfds);
2716 2739
	rb_fd_term(wfds);
2717
    if (efds)
2740
    }
2741
    if (efds) {
2742
	rb_fd_rcopy(except, efds);
2718 2743
	rb_fd_term(efds);
2744
    }
2719 2745

  
2720 2746
    return retval;
2721 2747
}