зеркало из https://github.com/github/ruby.git
Suppress -Wclobbered warnings
At 7afc16aa48
, now `BLOCKING_REGION`
contains `setjmp` call in `RB_VM_SAVE_MACHINE_CONTEXT`. By this
change, variables in blocks for this macro may be clobbered.
This commit is contained in:
Родитель
48ebd77e59
Коммит
d037c5196a
54
thread.c
54
thread.c
|
@ -1768,7 +1768,7 @@ rb_thread_mn_schedulable(VALUE thval)
|
||||||
VALUE
|
VALUE
|
||||||
rb_thread_io_blocking_call(rb_blocking_function_t *func, void *data1, int fd, int events)
|
rb_thread_io_blocking_call(rb_blocking_function_t *func, void *data1, int fd, int events)
|
||||||
{
|
{
|
||||||
rb_execution_context_t * volatile ec = GET_EC();
|
rb_execution_context_t *volatile ec = GET_EC();
|
||||||
rb_thread_t *th = rb_ec_thread_ptr(ec);
|
rb_thread_t *th = rb_ec_thread_ptr(ec);
|
||||||
|
|
||||||
RUBY_DEBUG_LOG("th:%u fd:%d ev:%d", rb_th_serial(th), fd, events);
|
RUBY_DEBUG_LOG("th:%u fd:%d ev:%d", rb_th_serial(th), fd, events);
|
||||||
|
@ -1796,6 +1796,7 @@ rb_thread_io_blocking_call(rb_blocking_function_t *func, void *data1, int fd, in
|
||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
}, ubf_select, waiting_fd.th, FALSE);
|
}, ubf_select, waiting_fd.th, FALSE);
|
||||||
|
|
||||||
|
th = rb_ec_thread_ptr(ec);
|
||||||
if (events &&
|
if (events &&
|
||||||
blocking_call_retryable_p((int)val, saved_errno) &&
|
blocking_call_retryable_p((int)val, saved_errno) &&
|
||||||
thread_io_wait_events(th, fd, events, NULL)) {
|
thread_io_wait_events(th, fd, events, NULL)) {
|
||||||
|
@ -1805,6 +1806,7 @@ rb_thread_io_blocking_call(rb_blocking_function_t *func, void *data1, int fd, in
|
||||||
}
|
}
|
||||||
EC_POP_TAG();
|
EC_POP_TAG();
|
||||||
|
|
||||||
|
th = rb_ec_thread_ptr(ec);
|
||||||
th->mn_schedulable = prev_mn_schedulable;
|
th->mn_schedulable = prev_mn_schedulable;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -4208,9 +4210,10 @@ rb_fd_set(int fd, rb_fdset_t *set)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wait_retryable(int *result, int errnum, rb_hrtime_t *rel, rb_hrtime_t end)
|
wait_retryable(volatile int *result, int errnum, rb_hrtime_t *rel, rb_hrtime_t end)
|
||||||
{
|
{
|
||||||
if (*result < 0) {
|
int r = *result;
|
||||||
|
if (r < 0) {
|
||||||
switch (errnum) {
|
switch (errnum) {
|
||||||
case EINTR:
|
case EINTR:
|
||||||
#ifdef ERESTART
|
#ifdef ERESTART
|
||||||
|
@ -4224,7 +4227,7 @@ wait_retryable(int *result, int errnum, rb_hrtime_t *rel, rb_hrtime_t end)
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else if (*result == 0) {
|
else if (r == 0) {
|
||||||
/* check for spurious wakeup */
|
/* check for spurious wakeup */
|
||||||
if (rel) {
|
if (rel) {
|
||||||
return !hrtime_update_expire(rel, end);
|
return !hrtime_update_expire(rel, end);
|
||||||
|
@ -4262,11 +4265,12 @@ static VALUE
|
||||||
do_select(VALUE p)
|
do_select(VALUE p)
|
||||||
{
|
{
|
||||||
struct select_set *set = (struct select_set *)p;
|
struct select_set *set = (struct select_set *)p;
|
||||||
int result = 0;
|
volatile int result = 0;
|
||||||
int lerrno;
|
int lerrno;
|
||||||
rb_hrtime_t *to, rel, end = 0;
|
rb_hrtime_t *to, rel, end = 0;
|
||||||
|
|
||||||
timeout_prepare(&to, &rel, &end, set->timeout);
|
timeout_prepare(&to, &rel, &end, set->timeout);
|
||||||
|
volatile rb_hrtime_t endtime = end;
|
||||||
#define restore_fdset(dst, src) \
|
#define restore_fdset(dst, src) \
|
||||||
((dst) ? rb_fd_dup(dst, src) : (void)0)
|
((dst) ? rb_fd_dup(dst, src) : (void)0)
|
||||||
#define do_select_update() \
|
#define do_select_update() \
|
||||||
|
@ -4282,15 +4286,15 @@ do_select(VALUE p)
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
if (!RUBY_VM_INTERRUPTED(set->th->ec)) {
|
if (!RUBY_VM_INTERRUPTED(set->th->ec)) {
|
||||||
result = native_fd_select(set->max,
|
result = native_fd_select(set->max,
|
||||||
set->rset, set->wset, set->eset,
|
set->rset, set->wset, set->eset,
|
||||||
rb_hrtime2timeval(&tv, to), set->th);
|
rb_hrtime2timeval(&tv, to), set->th);
|
||||||
if (result < 0) lerrno = errno;
|
if (result < 0) lerrno = errno;
|
||||||
}
|
}
|
||||||
}, ubf_select, set->th, TRUE);
|
}, ubf_select, set->th, TRUE);
|
||||||
|
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(set->th->ec); /* may raise */
|
RUBY_VM_CHECK_INTS_BLOCKING(set->th->ec); /* may raise */
|
||||||
} while (wait_retryable(&result, lerrno, to, end) && do_select_update());
|
} while (wait_retryable(&result, lerrno, to, endtime) && do_select_update());
|
||||||
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
errno = lerrno;
|
errno = lerrno;
|
||||||
|
@ -4352,6 +4356,23 @@ rb_thread_fd_select(int max, rb_fdset_t * read, rb_fdset_t * write, rb_fdset_t *
|
||||||
# define POLLERR_SET (0)
|
# define POLLERR_SET (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int
|
||||||
|
wait_for_single_fd_blocking_region(rb_thread_t *th, struct pollfd *fds, nfds_t nfds,
|
||||||
|
rb_hrtime_t *const to, volatile int *lerrno)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
volatile int result = 0;
|
||||||
|
|
||||||
|
*lerrno = 0;
|
||||||
|
BLOCKING_REGION(th, {
|
||||||
|
if (!RUBY_VM_INTERRUPTED(th->ec)) {
|
||||||
|
result = ppoll(fds, nfds, rb_hrtime2timespec(&ts, to), 0);
|
||||||
|
if (result < 0) *lerrno = errno;
|
||||||
|
}
|
||||||
|
}, ubf_select, th, TRUE);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* returns a mask of events
|
* returns a mask of events
|
||||||
*/
|
*/
|
||||||
|
@ -4363,7 +4384,7 @@ rb_thread_wait_for_single_fd(int fd, int events, struct timeval *timeout)
|
||||||
.events = (short)events,
|
.events = (short)events,
|
||||||
.revents = 0,
|
.revents = 0,
|
||||||
}};
|
}};
|
||||||
int result = 0;
|
volatile int result = 0;
|
||||||
nfds_t nfds;
|
nfds_t nfds;
|
||||||
struct waiting_fd wfd;
|
struct waiting_fd wfd;
|
||||||
enum ruby_tag_type state;
|
enum ruby_tag_type state;
|
||||||
|
@ -4387,17 +4408,8 @@ rb_thread_wait_for_single_fd(int fd, int events, struct timeval *timeout)
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(wfd.th->ec);
|
RUBY_VM_CHECK_INTS_BLOCKING(wfd.th->ec);
|
||||||
timeout_prepare(&to, &rel, &end, timeout);
|
timeout_prepare(&to, &rel, &end, timeout);
|
||||||
do {
|
do {
|
||||||
nfds = 1;
|
nfds = numberof(fds);
|
||||||
|
result = wait_for_single_fd_blocking_region(wfd.th, fds, nfds, to, &lerrno);
|
||||||
lerrno = 0;
|
|
||||||
BLOCKING_REGION(wfd.th, {
|
|
||||||
struct timespec ts;
|
|
||||||
|
|
||||||
if (!RUBY_VM_INTERRUPTED(wfd.th->ec)) {
|
|
||||||
result = ppoll(fds, nfds, rb_hrtime2timespec(&ts, to), 0);
|
|
||||||
if (result < 0) lerrno = errno;
|
|
||||||
}
|
|
||||||
}, ubf_select, wfd.th, TRUE);
|
|
||||||
|
|
||||||
RUBY_VM_CHECK_INTS_BLOCKING(wfd.th->ec);
|
RUBY_VM_CHECK_INTS_BLOCKING(wfd.th->ec);
|
||||||
} while (wait_retryable(&result, lerrno, to, end));
|
} while (wait_retryable(&result, lerrno, to, end));
|
||||||
|
|
Загрузка…
Ссылка в новой задаче