Skip to content

Commit 44fc3d0

Browse files
author
normal
committed
unrevert r63852 but keep SIGCHLD path disabled for win32
Reading win32/win32.c waitpid implementation, maybe waitpid(-1, ...) on that platform will never conflict with mjit use of waitpid. In any case, I've added WAITPID_USE_SIGCHLD macro to vm_core.h so it can be easy for Linux/BSD users to test (hopefully!) win32-compatible code. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63855 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent b3799b9 commit 44fc3d0

16 files changed

Lines changed: 627 additions & 230 deletions

configure.ac

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,7 @@ AS_CASE(["$target_os"],
766766
AS_IF([test $gcc_major -lt 4 -o \( $gcc_major -eq 4 -a $gcc_minor -lt 3 \)], [
767767
ac_cv_func___builtin_setjmp=no
768768
])
769+
with_setjmp_type=sigsetjmp # to hijack SIGCHLD handler
769770
AC_CACHE_CHECK(for broken crypt with 8bit chars, rb_cv_broken_crypt,
770771
[AC_TRY_RUN([
771772
#include <stdio.h>
@@ -1782,6 +1783,7 @@ AC_CHECK_FUNCS(getsid)
17821783
AC_CHECK_FUNCS(gettimeofday) # for making ac_cv_func_gettimeofday
17831784
AC_CHECK_FUNCS(getuidx)
17841785
AC_CHECK_FUNCS(gmtime_r)
1786+
AC_CHECK_FUNCS(grantpt)
17851787
AC_CHECK_FUNCS(initgroups)
17861788
AC_CHECK_FUNCS(ioctl)
17871789
AC_CHECK_FUNCS(isfinite)

ext/pty/pty.c

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -246,19 +246,13 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
246246
/* Unix98 PTY */
247247
int masterfd = -1, slavefd = -1;
248248
char *slavedevice;
249-
struct sigaction dfl, old;
250-
251-
dfl.sa_handler = SIG_DFL;
252-
dfl.sa_flags = 0;
253-
sigemptyset(&dfl.sa_mask);
254249

255250
#if defined(__sun) || (defined(__FreeBSD__) && __FreeBSD_version < 902000)
256251
/* workaround for Solaris 10: grantpt() doesn't work if FD_CLOEXEC is set. [ruby-dev:44688] */
257252
/* FreeBSD 9.2 or later supports O_CLOEXEC
258253
* http://www.freebsd.org/cgi/query-pr.cgi?pr=162374 */
259254
if ((masterfd = posix_openpt(O_RDWR|O_NOCTTY)) == -1) goto error;
260-
if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error;
261-
if (grantpt(masterfd) == -1) goto grantpt_error;
255+
if (rb_grantpt(masterfd) == -1) goto error;
262256
rb_fd_fix_cloexec(masterfd);
263257
#else
264258
{
@@ -272,10 +266,8 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
272266
if ((masterfd = posix_openpt(flags)) == -1) goto error;
273267
}
274268
rb_fd_fix_cloexec(masterfd);
275-
if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error;
276-
if (grantpt(masterfd) == -1) goto grantpt_error;
269+
if (rb_grantpt(masterfd) == -1) goto error;
277270
#endif
278-
if (sigaction(SIGCHLD, &old, NULL) == -1) goto error;
279271
if (unlockpt(masterfd) == -1) goto error;
280272
if ((slavedevice = ptsname(masterfd)) == NULL) goto error;
281273
if (no_mesg(slavedevice, nomesg) == -1) goto error;
@@ -293,8 +285,6 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
293285
strlcpy(SlaveName, slavedevice, DEVICELEN);
294286
return 0;
295287

296-
grantpt_error:
297-
sigaction(SIGCHLD, &old, NULL);
298288
error:
299289
if (slavefd != -1) close(slavefd);
300290
if (masterfd != -1) close(masterfd);
@@ -346,21 +336,17 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
346336

347337
extern char *ptsname(int);
348338
extern int unlockpt(int);
349-
extern int grantpt(int);
350339

351340
#if defined(__sun)
352341
/* workaround for Solaris 10: grantpt() doesn't work if FD_CLOEXEC is set. [ruby-dev:44688] */
353342
if((masterfd = open("/dev/ptmx", O_RDWR, 0)) == -1) goto error;
354-
s = signal(SIGCHLD, SIG_DFL);
355-
if(grantpt(masterfd) == -1) goto error;
343+
if(rb_grantpt(masterfd) == -1) goto error;
356344
rb_fd_fix_cloexec(masterfd);
357345
#else
358346
if((masterfd = rb_cloexec_open("/dev/ptmx", O_RDWR, 0)) == -1) goto error;
359347
rb_update_max_fd(masterfd);
360-
s = signal(SIGCHLD, SIG_DFL);
361-
if(grantpt(masterfd) == -1) goto error;
348+
if(rb_grantpt(masterfd) == -1) goto error;
362349
#endif
363-
signal(SIGCHLD, s);
364350
if(unlockpt(masterfd) == -1) goto error;
365351
if((slavedevice = ptsname(masterfd)) == NULL) goto error;
366352
if (no_mesg(slavedevice, nomesg) == -1) goto error;

internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2042,6 +2042,9 @@ VALUE rb_gcd_normal(VALUE self, VALUE other);
20422042
VALUE rb_gcd_gmp(VALUE x, VALUE y);
20432043
#endif
20442044

2045+
/* signal.c (export) */
2046+
int rb_grantpt(int fd);
2047+
20452048
/* string.c (export) */
20462049
#ifdef RUBY_ENCODING_H
20472050
/* internal use */

mjit.c

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
#include "constant.h"
8181
#include "id_table.h"
8282
#include "ruby_assert.h"
83+
#include "ruby/thread.h"
8384
#include "ruby/util.h"
8485
#include "ruby/version.h"
8586

@@ -118,6 +119,10 @@ extern void rb_native_cond_wait(rb_nativethread_cond_t *cond, rb_nativethread_lo
118119

119120
extern int rb_thread_create_mjit_thread(void (*child_hook)(void), void (*worker_func)(void));
120121

122+
/* process.c */
123+
rb_pid_t ruby_waitpid_locked(rb_vm_t *, rb_pid_t, int *status, int options,
124+
rb_nativethread_cond_t *cond);
125+
121126
#define RB_CONDATTR_CLOCK_MONOTONIC 1
122127

123128
#ifdef _WIN32
@@ -263,7 +268,7 @@ real_ms_time(void)
263268
static int
264269
sprint_uniq_filename(char *str, size_t size, unsigned long id, const char *prefix, const char *suffix)
265270
{
266-
return snprintf(str, size, "%s/%sp%luu%lu%s", tmp_dir, prefix, (unsigned long) getpid(), id, suffix);
271+
return snprintf(str, size, "%s/%sp%"PRI_PIDT_PREFIX"uu%lu%s", tmp_dir, prefix, getpid(), id, suffix);
267272
}
268273

269274
/* Return an unique file name in /tmp with PREFIX and SUFFIX and
@@ -401,22 +406,41 @@ start_process(const char *path, char *const *argv)
401406
static int
402407
exec_process(const char *path, char *const argv[])
403408
{
404-
int stat, exit_code;
409+
int stat, exit_code = -2;
405410
pid_t pid;
411+
rb_vm_t *vm = WAITPID_USE_SIGCHLD ? GET_VM() : 0;
412+
rb_nativethread_cond_t cond;
406413

407-
pid = start_process(path, argv);
408-
if (pid <= 0)
409-
return -2;
414+
if (vm) {
415+
rb_native_cond_initialize(&cond);
416+
rb_native_mutex_lock(&vm->waitpid_lock);
417+
}
410418

411-
for (;;) {
412-
waitpid(pid, &stat, 0);
413-
if (WIFEXITED(stat)) {
414-
exit_code = WEXITSTATUS(stat);
415-
break;
416-
} else if (WIFSIGNALED(stat)) {
417-
exit_code = -1;
419+
pid = start_process(path, argv);
420+
for (;pid > 0;) {
421+
pid_t r = vm ? ruby_waitpid_locked(vm, pid, &stat, 0, &cond)
422+
: waitpid(pid, &stat, 0);
423+
if (r == -1) {
424+
if (errno == EINTR) continue;
425+
fprintf(stderr, "[%"PRI_PIDT_PREFIX"d] waitpid(%"PRI_PIDT_PREFIX"d): %s (SIGCHLD=%d,%u)\n",
426+
getpid(), pid, strerror(errno),
427+
RUBY_SIGCHLD, SIGCHLD_LOSSY);
418428
break;
419429
}
430+
else if (r == pid) {
431+
if (WIFEXITED(stat)) {
432+
exit_code = WEXITSTATUS(stat);
433+
break;
434+
} else if (WIFSIGNALED(stat)) {
435+
exit_code = -1;
436+
break;
437+
}
438+
}
439+
}
440+
441+
if (vm) {
442+
rb_native_mutex_unlock(&vm->waitpid_lock);
443+
rb_native_cond_destroy(&cond);
420444
}
421445
return exit_code;
422446
}
@@ -1491,12 +1515,15 @@ mjit_init(struct mjit_options *opts)
14911515
static void
14921516
stop_worker(void)
14931517
{
1518+
rb_execution_context_t *ec = GET_EC();
1519+
14941520
stop_worker_p = TRUE;
14951521
while (!worker_stopped) {
14961522
verbose(3, "Sending cancel signal to worker");
14971523
CRITICAL_SECTION_START(3, "in stop_worker");
14981524
rb_native_cond_broadcast(&mjit_worker_wakeup);
14991525
CRITICAL_SECTION_FINISH(3, "in stop_worker");
1526+
RUBY_VM_CHECK_INTS(ec);
15001527
}
15011528
}
15021529

0 commit comments

Comments
 (0)