Skip to content

Commit

Permalink
unrevert r63852 but keep SIGCHLD path disabled for win32
Browse files Browse the repository at this point in the history
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
  • Loading branch information
normal committed Jul 5, 2018
1 parent b3799b9 commit 44fc3d0
Show file tree
Hide file tree
Showing 16 changed files with 627 additions and 230 deletions.
2 changes: 2 additions & 0 deletions configure.ac
Expand Up @@ -766,6 +766,7 @@ AS_CASE(["$target_os"],
AS_IF([test $gcc_major -lt 4 -o \( $gcc_major -eq 4 -a $gcc_minor -lt 3 \)], [
ac_cv_func___builtin_setjmp=no
])
with_setjmp_type=sigsetjmp # to hijack SIGCHLD handler
AC_CACHE_CHECK(for broken crypt with 8bit chars, rb_cv_broken_crypt,
[AC_TRY_RUN([
#include <stdio.h>
Expand Down Expand Up @@ -1782,6 +1783,7 @@ AC_CHECK_FUNCS(getsid)
AC_CHECK_FUNCS(gettimeofday) # for making ac_cv_func_gettimeofday
AC_CHECK_FUNCS(getuidx)
AC_CHECK_FUNCS(gmtime_r)
AC_CHECK_FUNCS(grantpt)
AC_CHECK_FUNCS(initgroups)
AC_CHECK_FUNCS(ioctl)
AC_CHECK_FUNCS(isfinite)
Expand Down
22 changes: 4 additions & 18 deletions ext/pty/pty.c
Expand Up @@ -246,19 +246,13 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
/* Unix98 PTY */
int masterfd = -1, slavefd = -1;
char *slavedevice;
struct sigaction dfl, old;

dfl.sa_handler = SIG_DFL;
dfl.sa_flags = 0;
sigemptyset(&dfl.sa_mask);

#if defined(__sun) || (defined(__FreeBSD__) && __FreeBSD_version < 902000)
/* workaround for Solaris 10: grantpt() doesn't work if FD_CLOEXEC is set. [ruby-dev:44688] */
/* FreeBSD 9.2 or later supports O_CLOEXEC
* http://www.freebsd.org/cgi/query-pr.cgi?pr=162374 */
if ((masterfd = posix_openpt(O_RDWR|O_NOCTTY)) == -1) goto error;
if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error;
if (grantpt(masterfd) == -1) goto grantpt_error;
if (rb_grantpt(masterfd) == -1) goto error;
rb_fd_fix_cloexec(masterfd);
#else
{
Expand All @@ -272,10 +266,8 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
if ((masterfd = posix_openpt(flags)) == -1) goto error;
}
rb_fd_fix_cloexec(masterfd);
if (sigaction(SIGCHLD, &dfl, &old) == -1) goto error;
if (grantpt(masterfd) == -1) goto grantpt_error;
if (rb_grantpt(masterfd) == -1) goto error;
#endif
if (sigaction(SIGCHLD, &old, NULL) == -1) goto error;
if (unlockpt(masterfd) == -1) goto error;
if ((slavedevice = ptsname(masterfd)) == NULL) goto error;
if (no_mesg(slavedevice, nomesg) == -1) goto error;
Expand All @@ -293,8 +285,6 @@ get_device_once(int *master, int *slave, char SlaveName[DEVICELEN], int nomesg,
strlcpy(SlaveName, slavedevice, DEVICELEN);
return 0;

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

extern char *ptsname(int);
extern int unlockpt(int);
extern int grantpt(int);

#if defined(__sun)
/* workaround for Solaris 10: grantpt() doesn't work if FD_CLOEXEC is set. [ruby-dev:44688] */
if((masterfd = open("/dev/ptmx", O_RDWR, 0)) == -1) goto error;
s = signal(SIGCHLD, SIG_DFL);
if(grantpt(masterfd) == -1) goto error;
if(rb_grantpt(masterfd) == -1) goto error;
rb_fd_fix_cloexec(masterfd);
#else
if((masterfd = rb_cloexec_open("/dev/ptmx", O_RDWR, 0)) == -1) goto error;
rb_update_max_fd(masterfd);
s = signal(SIGCHLD, SIG_DFL);
if(grantpt(masterfd) == -1) goto error;
if(rb_grantpt(masterfd) == -1) goto error;
#endif
signal(SIGCHLD, s);
if(unlockpt(masterfd) == -1) goto error;
if((slavedevice = ptsname(masterfd)) == NULL) goto error;
if (no_mesg(slavedevice, nomesg) == -1) goto error;
Expand Down
3 changes: 3 additions & 0 deletions internal.h
Expand Up @@ -2042,6 +2042,9 @@ VALUE rb_gcd_normal(VALUE self, VALUE other);
VALUE rb_gcd_gmp(VALUE x, VALUE y);
#endif

/* signal.c (export) */
int rb_grantpt(int fd);

/* string.c (export) */
#ifdef RUBY_ENCODING_H
/* internal use */
Expand Down
51 changes: 39 additions & 12 deletions mjit.c
Expand Up @@ -80,6 +80,7 @@
#include "constant.h"
#include "id_table.h"
#include "ruby_assert.h"
#include "ruby/thread.h"
#include "ruby/util.h"
#include "ruby/version.h"

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

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

/* process.c */
rb_pid_t ruby_waitpid_locked(rb_vm_t *, rb_pid_t, int *status, int options,
rb_nativethread_cond_t *cond);

#define RB_CONDATTR_CLOCK_MONOTONIC 1

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

/* Return an unique file name in /tmp with PREFIX and SUFFIX and
Expand Down Expand Up @@ -401,22 +406,41 @@ start_process(const char *path, char *const *argv)
static int
exec_process(const char *path, char *const argv[])
{
int stat, exit_code;
int stat, exit_code = -2;
pid_t pid;
rb_vm_t *vm = WAITPID_USE_SIGCHLD ? GET_VM() : 0;
rb_nativethread_cond_t cond;

pid = start_process(path, argv);
if (pid <= 0)
return -2;
if (vm) {
rb_native_cond_initialize(&cond);
rb_native_mutex_lock(&vm->waitpid_lock);
}

for (;;) {
waitpid(pid, &stat, 0);
if (WIFEXITED(stat)) {
exit_code = WEXITSTATUS(stat);
break;
} else if (WIFSIGNALED(stat)) {
exit_code = -1;
pid = start_process(path, argv);
for (;pid > 0;) {
pid_t r = vm ? ruby_waitpid_locked(vm, pid, &stat, 0, &cond)
: waitpid(pid, &stat, 0);
if (r == -1) {
if (errno == EINTR) continue;
fprintf(stderr, "[%"PRI_PIDT_PREFIX"d] waitpid(%"PRI_PIDT_PREFIX"d): %s (SIGCHLD=%d,%u)\n",
getpid(), pid, strerror(errno),
RUBY_SIGCHLD, SIGCHLD_LOSSY);
break;
}
else if (r == pid) {
if (WIFEXITED(stat)) {
exit_code = WEXITSTATUS(stat);
break;
} else if (WIFSIGNALED(stat)) {
exit_code = -1;
break;
}
}
}

if (vm) {
rb_native_mutex_unlock(&vm->waitpid_lock);
rb_native_cond_destroy(&cond);
}
return exit_code;
}
Expand Down Expand Up @@ -1491,12 +1515,15 @@ mjit_init(struct mjit_options *opts)
static void
stop_worker(void)
{
rb_execution_context_t *ec = GET_EC();

stop_worker_p = TRUE;
while (!worker_stopped) {
verbose(3, "Sending cancel signal to worker");
CRITICAL_SECTION_START(3, "in stop_worker");
rb_native_cond_broadcast(&mjit_worker_wakeup);
CRITICAL_SECTION_FINISH(3, "in stop_worker");
RUBY_VM_CHECK_INTS(ec);
}
}

Expand Down

0 comments on commit 44fc3d0

Please sign in to comment.