mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* eval.c (rb_thread_save_context, rb_thread_restore_context):
sandbox hook to save and restore sandbox state. * eval.c (thread_no_ensure): added THREAD_NO_ENSURE thread flag. * eval.c (rb_thread_kill_bang): Thread#kill! uses the above flag to circumvent ensure, in order to prevent endless loops. [ruby-core:08768] * eval.c (rb_thread_kill): fix Thread#kill docs, which returns the thread object in all cases. * node.h: expose the rb_jmpbuf_t and rb_thread_t structs, along with the thread flags. used by the sandbox extension. * ruby.h: extern rb_eThreadError, so sandbox can swap it. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@11000 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
0837449ac2
commit
41256fd432
4 changed files with 194 additions and 101 deletions
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
||||||
|
Sat Sep 23 23:24:57 2006 why the lucky stiff <why@ruby-lang.org>
|
||||||
|
|
||||||
|
* eval.c (rb_thread_save_context, rb_thread_restore_context):
|
||||||
|
sandbox hook to save and restore sandbox state.
|
||||||
|
|
||||||
|
* eval.c (thread_no_ensure): added THREAD_NO_ENSURE thread flag.
|
||||||
|
|
||||||
|
* eval.c (rb_thread_kill_bang): Thread#kill! uses the above flag
|
||||||
|
to circumvent ensure, in order to prevent endless loops.
|
||||||
|
[ruby-core:08768]
|
||||||
|
|
||||||
|
* eval.c (rb_thread_kill): fix Thread#kill docs, which returns
|
||||||
|
the thread object in all cases.
|
||||||
|
|
||||||
|
* node.h: expose the rb_jmpbuf_t and rb_thread_t structs, along
|
||||||
|
with the thread flags. used by the sandbox extension.
|
||||||
|
|
||||||
|
* ruby.h: extern rb_eThreadError, so sandbox can swap it.
|
||||||
|
|
||||||
Sat Sep 23 21:34:15 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
|
Sat Sep 23 21:34:15 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
* lib/cgi.rb (CGI::QueryExtension::read_multipart): CGI content
|
* lib/cgi.rb (CGI::QueryExtension::read_multipart): CGI content
|
||||||
|
|
184
eval.c
184
eval.c
|
@ -29,11 +29,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#if defined(HAVE_GETCONTEXT) && defined(HAVE_SETCONTEXT)
|
|
||||||
#include <ucontext.h>
|
|
||||||
#define USE_CONTEXT
|
|
||||||
#endif
|
|
||||||
#include <setjmp.h>
|
|
||||||
|
|
||||||
#include "st.h"
|
#include "st.h"
|
||||||
#include "dln.h"
|
#include "dln.h"
|
||||||
|
@ -90,10 +85,6 @@ char *strrchr _((const char*,const char));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_CONTEXT
|
#ifdef USE_CONTEXT
|
||||||
typedef struct {
|
|
||||||
ucontext_t context;
|
|
||||||
volatile int status;
|
|
||||||
} rb_jmpbuf_t[1];
|
|
||||||
|
|
||||||
NORETURN(static void rb_jump_context(rb_jmpbuf_t, int));
|
NORETURN(static void rb_jump_context(rb_jmpbuf_t, int));
|
||||||
static inline void
|
static inline void
|
||||||
|
@ -202,7 +193,6 @@ static int volatile freebsd_clear_carry_flag = 0;
|
||||||
POST_GETCONTEXT, \
|
POST_GETCONTEXT, \
|
||||||
(j)->status)
|
(j)->status)
|
||||||
#else
|
#else
|
||||||
typedef jmp_buf rb_jmpbuf_t;
|
|
||||||
# if !defined(setjmp) && defined(HAVE__SETJMP)
|
# if !defined(setjmp) && defined(HAVE__SETJMP)
|
||||||
# define ruby_setjmp(just_before_setjmp, env) \
|
# define ruby_setjmp(just_before_setjmp, env) \
|
||||||
((just_before_setjmp), _setjmp(env))
|
((just_before_setjmp), _setjmp(env))
|
||||||
|
@ -253,6 +243,8 @@ static int scope_vmode;
|
||||||
#define SCOPE_SET(f) (scope_vmode=(f))
|
#define SCOPE_SET(f) (scope_vmode=(f))
|
||||||
#define SCOPE_TEST(f) (scope_vmode&(f))
|
#define SCOPE_TEST(f) (scope_vmode&(f))
|
||||||
|
|
||||||
|
VALUE (*ruby_sandbox_save)(struct thread *) = NULL;
|
||||||
|
VALUE (*ruby_sandbox_restore)(struct thread *) = NULL;
|
||||||
NODE* ruby_current_node;
|
NODE* ruby_current_node;
|
||||||
int ruby_safe_level = 0;
|
int ruby_safe_level = 0;
|
||||||
/* safe-level:
|
/* safe-level:
|
||||||
|
@ -1081,9 +1073,8 @@ NODE *ruby_top_cref;
|
||||||
ruby_scope = _scope; \
|
ruby_scope = _scope; \
|
||||||
scope_vmode = SCOPE_PUBLIC
|
scope_vmode = SCOPE_PUBLIC
|
||||||
|
|
||||||
typedef struct thread * rb_thread_t;
|
rb_thread_t curr_thread = 0;
|
||||||
static rb_thread_t curr_thread = 0;
|
rb_thread_t main_thread;
|
||||||
static rb_thread_t main_thread;
|
|
||||||
static void scope_dup _((struct SCOPE *));
|
static void scope_dup _((struct SCOPE *));
|
||||||
|
|
||||||
#define POP_SCOPE() \
|
#define POP_SCOPE() \
|
||||||
|
@ -1440,6 +1431,8 @@ static void rb_thread_wait_other_threads _((void));
|
||||||
static int thread_set_raised();
|
static int thread_set_raised();
|
||||||
static int thread_reset_raised();
|
static int thread_reset_raised();
|
||||||
|
|
||||||
|
static int thread_no_ensure _((void));
|
||||||
|
|
||||||
static VALUE exception_error;
|
static VALUE exception_error;
|
||||||
static VALUE sysstack_error;
|
static VALUE sysstack_error;
|
||||||
|
|
||||||
|
@ -3310,7 +3303,7 @@ rb_eval(self, n)
|
||||||
result = rb_eval(self, node->nd_head);
|
result = rb_eval(self, node->nd_head);
|
||||||
}
|
}
|
||||||
POP_TAG();
|
POP_TAG();
|
||||||
if (node->nd_ensr) {
|
if (node->nd_ensr && !thread_no_ensure()) {
|
||||||
VALUE retval = prot_tag->retval; /* save retval */
|
VALUE retval = prot_tag->retval; /* save retval */
|
||||||
VALUE errinfo = ruby_errinfo;
|
VALUE errinfo = ruby_errinfo;
|
||||||
|
|
||||||
|
@ -4743,7 +4736,7 @@ rb_f_block_given_p()
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE rb_eThreadError;
|
VALUE rb_eThreadError;
|
||||||
|
|
||||||
NORETURN(static void proc_jump_error(int, VALUE));
|
NORETURN(static void proc_jump_error(int, VALUE));
|
||||||
static void
|
static void
|
||||||
|
@ -5456,7 +5449,9 @@ rb_ensure(b_proc, data1, e_proc, data2)
|
||||||
}
|
}
|
||||||
POP_TAG();
|
POP_TAG();
|
||||||
retval = prot_tag ? prot_tag->retval : Qnil; /* save retval */
|
retval = prot_tag ? prot_tag->retval : Qnil; /* save retval */
|
||||||
|
if (!thread_no_ensure()) {
|
||||||
(*e_proc)(data2);
|
(*e_proc)(data2);
|
||||||
|
}
|
||||||
if (prot_tag) return_value(retval);
|
if (prot_tag) return_value(retval);
|
||||||
if (state) JUMP_TAG(state);
|
if (state) JUMP_TAG(state);
|
||||||
return result;
|
return result;
|
||||||
|
@ -9747,13 +9742,6 @@ VALUE rb_cThread;
|
||||||
|
|
||||||
extern VALUE rb_last_status;
|
extern VALUE rb_last_status;
|
||||||
|
|
||||||
enum thread_status {
|
|
||||||
THREAD_TO_KILL,
|
|
||||||
THREAD_RUNNABLE,
|
|
||||||
THREAD_STOPPED,
|
|
||||||
THREAD_KILLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define WAIT_FD (1<<0)
|
#define WAIT_FD (1<<0)
|
||||||
#define WAIT_SELECT (1<<1)
|
#define WAIT_SELECT (1<<1)
|
||||||
#define WAIT_TIME (1<<2)
|
#define WAIT_TIME (1<<2)
|
||||||
|
@ -9773,70 +9761,10 @@ enum thread_status {
|
||||||
|
|
||||||
/* typedef struct thread * rb_thread_t; */
|
/* typedef struct thread * rb_thread_t; */
|
||||||
|
|
||||||
struct thread {
|
|
||||||
struct thread *next, *prev;
|
|
||||||
rb_jmpbuf_t context;
|
|
||||||
#ifdef SAVE_WIN32_EXCEPTION_LIST
|
|
||||||
DWORD win32_exception_list;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VALUE result;
|
|
||||||
|
|
||||||
long stk_len;
|
|
||||||
long stk_max;
|
|
||||||
VALUE *stk_ptr;
|
|
||||||
VALUE *stk_pos;
|
|
||||||
#ifdef __ia64
|
|
||||||
long bstr_len;
|
|
||||||
long bstr_max;
|
|
||||||
VALUE *bstr_ptr;
|
|
||||||
VALUE *bstr_pos;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct FRAME *frame;
|
|
||||||
struct SCOPE *scope;
|
|
||||||
struct RVarmap *dyna_vars;
|
|
||||||
struct BLOCK *block;
|
|
||||||
struct iter *iter;
|
|
||||||
struct tag *tag;
|
|
||||||
VALUE klass;
|
|
||||||
VALUE wrapper;
|
|
||||||
NODE *cref;
|
|
||||||
|
|
||||||
int flags; /* misc. states (vmode/rb_trap_immediate/raised) */
|
|
||||||
|
|
||||||
NODE *node;
|
|
||||||
|
|
||||||
int tracing;
|
|
||||||
VALUE errinfo;
|
|
||||||
VALUE last_status;
|
|
||||||
VALUE last_line;
|
|
||||||
VALUE last_match;
|
|
||||||
|
|
||||||
int safe;
|
|
||||||
|
|
||||||
enum thread_status status;
|
|
||||||
int wait_for;
|
|
||||||
int fd;
|
|
||||||
fd_set readfds;
|
|
||||||
fd_set writefds;
|
|
||||||
fd_set exceptfds;
|
|
||||||
int select_value;
|
|
||||||
double delay;
|
|
||||||
rb_thread_t join;
|
|
||||||
|
|
||||||
int abort;
|
|
||||||
int priority;
|
|
||||||
VALUE thgroup;
|
|
||||||
|
|
||||||
st_table *locals;
|
|
||||||
|
|
||||||
VALUE thread;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define THREAD_RAISED 0x200 /* temporary flag */
|
#define THREAD_RAISED 0x200 /* temporary flag */
|
||||||
#define THREAD_TERMINATING 0x400 /* persistent flag */
|
#define THREAD_TERMINATING 0x400 /* persistent flag */
|
||||||
#define THREAD_FLAGS_MASK 0x400 /* mask for persistent flags */
|
#define THREAD_NO_ENSURE 0x800 /* persistent flag */
|
||||||
|
#define THREAD_FLAGS_MASK 0xc00 /* mask for persistent flags */
|
||||||
|
|
||||||
#define FOREACH_THREAD_FROM(f,x) x = f; do { x = x->next;
|
#define FOREACH_THREAD_FROM(f,x) x = f; do { x = x->next;
|
||||||
#define END_FOREACH_FROM(f,x) } while (x != f)
|
#define END_FOREACH_FROM(f,x) } while (x != f)
|
||||||
|
@ -9904,6 +9832,12 @@ thread_reset_raised()
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
thread_no_ensure()
|
||||||
|
{
|
||||||
|
return ((curr_thread->flags & THREAD_NO_ENSURE) == THREAD_NO_ENSURE);
|
||||||
|
}
|
||||||
|
|
||||||
static void rb_thread_ready _((rb_thread_t));
|
static void rb_thread_ready _((rb_thread_t));
|
||||||
|
|
||||||
static VALUE run_trap_eval _((VALUE));
|
static VALUE run_trap_eval _((VALUE));
|
||||||
|
@ -10034,6 +9968,7 @@ thread_mark(th)
|
||||||
rb_gc_mark(th->last_match);
|
rb_gc_mark(th->last_match);
|
||||||
rb_mark_tbl(th->locals);
|
rb_mark_tbl(th->locals);
|
||||||
rb_gc_mark(th->thgroup);
|
rb_gc_mark(th->thgroup);
|
||||||
|
rb_gc_mark_maybe(th->sandbox);
|
||||||
|
|
||||||
/* mark data in copied stack */
|
/* mark data in copied stack */
|
||||||
if (th == curr_thread) return;
|
if (th == curr_thread) return;
|
||||||
|
@ -10238,6 +10173,10 @@ rb_thread_save_context(th)
|
||||||
th->safe = ruby_safe_level;
|
th->safe = ruby_safe_level;
|
||||||
|
|
||||||
th->node = ruby_current_node;
|
th->node = ruby_current_node;
|
||||||
|
if (ruby_sandbox_save != NULL)
|
||||||
|
{
|
||||||
|
ruby_sandbox_save(th);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -10295,6 +10234,10 @@ rb_thread_restore_context_0(rb_thread_t th, int exit, void *vp)
|
||||||
static VALUE tval;
|
static VALUE tval;
|
||||||
|
|
||||||
rb_trap_immediate = 0; /* inhibit interrupts from here */
|
rb_trap_immediate = 0; /* inhibit interrupts from here */
|
||||||
|
if (ruby_sandbox_restore != NULL)
|
||||||
|
{
|
||||||
|
ruby_sandbox_restore(th);
|
||||||
|
}
|
||||||
ruby_frame = th->frame;
|
ruby_frame = th->frame;
|
||||||
ruby_scope = th->scope;
|
ruby_scope = th->scope;
|
||||||
ruby_class = th->klass;
|
ruby_class = th->klass;
|
||||||
|
@ -11232,16 +11175,34 @@ rb_thread_run(thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
kill_thread(th, flags)
|
||||||
|
rb_thread_t th;
|
||||||
|
int flags;
|
||||||
|
{
|
||||||
|
if (th != curr_thread && th->safe < 4) {
|
||||||
|
rb_secure(4);
|
||||||
|
}
|
||||||
|
if (th->status == THREAD_TO_KILL || th->status == THREAD_KILLED)
|
||||||
|
return;
|
||||||
|
if (th == th->next || th == main_thread) rb_exit(EXIT_SUCCESS);
|
||||||
|
|
||||||
|
rb_thread_ready(th);
|
||||||
|
th->flags |= flags;
|
||||||
|
th->status = THREAD_TO_KILL;
|
||||||
|
if (!rb_thread_critical) rb_thread_schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* thr.exit => thr or nil
|
* thr.exit => thr
|
||||||
* thr.kill => thr or nil
|
* thr.kill => thr
|
||||||
* thr.terminate => thr or nil
|
* thr.terminate => thr
|
||||||
*
|
*
|
||||||
* Terminates <i>thr</i> and schedules another thread to be run. If this thread
|
* Terminates <i>thr</i> and schedules another thread to be run, returning
|
||||||
* is already marked to be killed, <code>exit</code> returns the
|
* the terminated <code>Thread</code>. If this is the main thread, or the
|
||||||
* <code>Thread</code>. If this is the main thread, or the last thread, exits
|
* last thread, exits the process.
|
||||||
* the process.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -11250,20 +11211,33 @@ rb_thread_kill(thread)
|
||||||
{
|
{
|
||||||
rb_thread_t th = rb_thread_check(thread);
|
rb_thread_t th = rb_thread_check(thread);
|
||||||
|
|
||||||
if (th != curr_thread && th->safe < 4) {
|
kill_thread(th, 0);
|
||||||
rb_secure(4);
|
|
||||||
}
|
|
||||||
if (th->status == THREAD_TO_KILL || th->status == THREAD_KILLED)
|
|
||||||
return thread;
|
return thread;
|
||||||
if (th == th->next || th == main_thread) rb_exit(EXIT_SUCCESS);
|
|
||||||
|
|
||||||
rb_thread_ready(th);
|
|
||||||
th->status = THREAD_TO_KILL;
|
|
||||||
if (!rb_thread_critical) rb_thread_schedule();
|
|
||||||
return thread;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* thr.exit! => thr
|
||||||
|
* thr.kill! => thr
|
||||||
|
* thr.terminate! => thr
|
||||||
|
*
|
||||||
|
* Terminates <i>thr</i> without calling ensure clauses and schedules
|
||||||
|
* another thread to be run, returning the terminated <code>Thread</code>.
|
||||||
|
* If this is the main thread, or the last thread, exits the process.
|
||||||
|
*
|
||||||
|
* See <code>Thread#exit</code> for the safer version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
rb_thread_kill_bang(thread)
|
||||||
|
VALUE thread;
|
||||||
|
{
|
||||||
|
rb_thread_t th = rb_thread_check(thread);
|
||||||
|
kill_thread(th, THREAD_NO_ENSURE);
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* Thread.kill(thread) => thread
|
* Thread.kill(thread) => thread
|
||||||
|
@ -11658,6 +11632,11 @@ rb_thread_group(thread)
|
||||||
th->thgroup = thgroup_default;\
|
th->thgroup = thgroup_default;\
|
||||||
th->locals = 0;\
|
th->locals = 0;\
|
||||||
th->thread = 0;\
|
th->thread = 0;\
|
||||||
|
if (curr_thread == 0) {\
|
||||||
|
th->sandbox = Qnil;\
|
||||||
|
} else {\
|
||||||
|
th->sandbox = curr_thread->sandbox;\
|
||||||
|
}\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static rb_thread_t
|
static rb_thread_t
|
||||||
|
@ -12915,6 +12894,9 @@ Init_Thread()
|
||||||
rb_define_method(rb_cThread, "kill", rb_thread_kill, 0);
|
rb_define_method(rb_cThread, "kill", rb_thread_kill, 0);
|
||||||
rb_define_method(rb_cThread, "terminate", rb_thread_kill, 0);
|
rb_define_method(rb_cThread, "terminate", rb_thread_kill, 0);
|
||||||
rb_define_method(rb_cThread, "exit", rb_thread_kill, 0);
|
rb_define_method(rb_cThread, "exit", rb_thread_kill, 0);
|
||||||
|
rb_define_method(rb_cThread, "kill!", rb_thread_kill_bang, 0);
|
||||||
|
rb_define_method(rb_cThread, "terminate!", rb_thread_kill_bang, 0);
|
||||||
|
rb_define_method(rb_cThread, "exit!", rb_thread_kill_bang, 0);
|
||||||
rb_define_method(rb_cThread, "value", rb_thread_value, 0);
|
rb_define_method(rb_cThread, "value", rb_thread_value, 0);
|
||||||
rb_define_method(rb_cThread, "status", rb_thread_status, 0);
|
rb_define_method(rb_cThread, "status", rb_thread_status, 0);
|
||||||
rb_define_method(rb_cThread, "join", rb_thread_join_m, -1);
|
rb_define_method(rb_cThread, "join", rb_thread_join_m, -1);
|
||||||
|
|
91
node.h
91
node.h
|
@ -374,6 +374,97 @@ typedef void (*rb_event_hook_func_t) _((rb_event_t,NODE*,VALUE,ID,VALUE));
|
||||||
void rb_add_event_hook _((rb_event_hook_func_t,rb_event_t));
|
void rb_add_event_hook _((rb_event_hook_func_t,rb_event_t));
|
||||||
int rb_remove_event_hook _((rb_event_hook_func_t));
|
int rb_remove_event_hook _((rb_event_hook_func_t));
|
||||||
|
|
||||||
|
#if defined(HAVE_GETCONTEXT) && defined(HAVE_SETCONTEXT)
|
||||||
|
#include <ucontext.h>
|
||||||
|
#define USE_CONTEXT
|
||||||
|
#endif
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include "st.h"
|
||||||
|
|
||||||
|
#ifdef USE_CONTEXT
|
||||||
|
typedef struct {
|
||||||
|
ucontext_t context;
|
||||||
|
volatile int status;
|
||||||
|
} rb_jmpbuf_t[1];
|
||||||
|
#else
|
||||||
|
typedef jmp_buf rb_jmpbuf_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum thread_status {
|
||||||
|
THREAD_TO_KILL,
|
||||||
|
THREAD_RUNNABLE,
|
||||||
|
THREAD_STOPPED,
|
||||||
|
THREAD_KILLED,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct thread * rb_thread_t;
|
||||||
|
|
||||||
|
struct thread {
|
||||||
|
struct thread *next, *prev;
|
||||||
|
rb_jmpbuf_t context;
|
||||||
|
#ifdef SAVE_WIN32_EXCEPTION_LIST
|
||||||
|
DWORD win32_exception_list;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VALUE result;
|
||||||
|
|
||||||
|
long stk_len;
|
||||||
|
long stk_max;
|
||||||
|
VALUE *stk_ptr;
|
||||||
|
VALUE *stk_pos;
|
||||||
|
#ifdef __ia64__
|
||||||
|
VALUE *bstr_ptr;
|
||||||
|
long bstr_len;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct FRAME *frame;
|
||||||
|
struct SCOPE *scope;
|
||||||
|
struct RVarmap *dyna_vars;
|
||||||
|
struct BLOCK *block;
|
||||||
|
struct iter *iter;
|
||||||
|
struct tag *tag;
|
||||||
|
VALUE klass;
|
||||||
|
VALUE wrapper;
|
||||||
|
NODE *cref;
|
||||||
|
|
||||||
|
int flags; /* misc. states (vmode/rb_trap_immediate/raised) */
|
||||||
|
|
||||||
|
NODE *node;
|
||||||
|
|
||||||
|
int tracing;
|
||||||
|
VALUE errinfo;
|
||||||
|
VALUE last_status;
|
||||||
|
VALUE last_line;
|
||||||
|
VALUE last_match;
|
||||||
|
|
||||||
|
int safe;
|
||||||
|
|
||||||
|
enum thread_status status;
|
||||||
|
int wait_for;
|
||||||
|
int fd;
|
||||||
|
fd_set readfds;
|
||||||
|
fd_set writefds;
|
||||||
|
fd_set exceptfds;
|
||||||
|
int select_value;
|
||||||
|
double delay;
|
||||||
|
rb_thread_t join;
|
||||||
|
|
||||||
|
int abort;
|
||||||
|
int priority;
|
||||||
|
VALUE thgroup;
|
||||||
|
|
||||||
|
st_table *locals;
|
||||||
|
|
||||||
|
VALUE thread;
|
||||||
|
|
||||||
|
VALUE sandbox;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern VALUE (*ruby_sandbox_save)(struct thread *);
|
||||||
|
extern VALUE (*ruby_sandbox_restore)(struct thread *);
|
||||||
|
extern rb_thread_t curr_thread;
|
||||||
|
extern rb_thread_t main_thread;
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
} /* extern "C" { */
|
} /* extern "C" { */
|
||||||
#endif
|
#endif
|
||||||
|
|
1
ruby.h
1
ruby.h
|
@ -645,6 +645,7 @@ RUBY_EXTERN VALUE rb_eIOError;
|
||||||
RUBY_EXTERN VALUE rb_eRuntimeError;
|
RUBY_EXTERN VALUE rb_eRuntimeError;
|
||||||
RUBY_EXTERN VALUE rb_eSecurityError;
|
RUBY_EXTERN VALUE rb_eSecurityError;
|
||||||
RUBY_EXTERN VALUE rb_eSystemCallError;
|
RUBY_EXTERN VALUE rb_eSystemCallError;
|
||||||
|
RUBY_EXTERN VALUE rb_eThreadError;
|
||||||
RUBY_EXTERN VALUE rb_eTypeError;
|
RUBY_EXTERN VALUE rb_eTypeError;
|
||||||
RUBY_EXTERN VALUE rb_eZeroDivError;
|
RUBY_EXTERN VALUE rb_eZeroDivError;
|
||||||
RUBY_EXTERN VALUE rb_eNotImpError;
|
RUBY_EXTERN VALUE rb_eNotImpError;
|
||||||
|
|
Loading…
Add table
Reference in a new issue