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>
 | 
			
		||||
 | 
			
		||||
	* lib/cgi.rb (CGI::QueryExtension::read_multipart): CGI content
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										184
									
								
								eval.c
									
										
									
									
									
								
							
							
						
						
									
										184
									
								
								eval.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -29,11 +29,6 @@
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#if defined(HAVE_GETCONTEXT) && defined(HAVE_SETCONTEXT)
 | 
			
		||||
#include <ucontext.h>
 | 
			
		||||
#define USE_CONTEXT
 | 
			
		||||
#endif
 | 
			
		||||
#include <setjmp.h>
 | 
			
		||||
 | 
			
		||||
#include "st.h"
 | 
			
		||||
#include "dln.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -90,10 +85,6 @@ char *strrchr _((const char*,const char));
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#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));
 | 
			
		||||
static inline void
 | 
			
		||||
| 
						 | 
				
			
			@ -202,7 +193,6 @@ static int volatile freebsd_clear_carry_flag = 0;
 | 
			
		|||
     POST_GETCONTEXT, \
 | 
			
		||||
     (j)->status)
 | 
			
		||||
#else
 | 
			
		||||
typedef jmp_buf rb_jmpbuf_t;
 | 
			
		||||
#  if !defined(setjmp) && defined(HAVE__SETJMP)
 | 
			
		||||
#    define ruby_setjmp(just_before_setjmp, env) \
 | 
			
		||||
       ((just_before_setjmp), _setjmp(env))
 | 
			
		||||
| 
						 | 
				
			
			@ -253,6 +243,8 @@ static int scope_vmode;
 | 
			
		|||
#define SCOPE_SET(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;
 | 
			
		||||
int ruby_safe_level = 0;
 | 
			
		||||
/* safe-level:
 | 
			
		||||
| 
						 | 
				
			
			@ -1081,9 +1073,8 @@ NODE *ruby_top_cref;
 | 
			
		|||
    ruby_scope = _scope;		\
 | 
			
		||||
    scope_vmode = SCOPE_PUBLIC
 | 
			
		||||
 | 
			
		||||
typedef struct thread * rb_thread_t;
 | 
			
		||||
static rb_thread_t curr_thread = 0;
 | 
			
		||||
static rb_thread_t main_thread;
 | 
			
		||||
rb_thread_t curr_thread = 0;
 | 
			
		||||
rb_thread_t main_thread;
 | 
			
		||||
static void scope_dup _((struct SCOPE *));
 | 
			
		||||
 | 
			
		||||
#define POP_SCOPE() 			\
 | 
			
		||||
| 
						 | 
				
			
			@ -1440,6 +1431,8 @@ static void rb_thread_wait_other_threads _((void));
 | 
			
		|||
static int thread_set_raised();
 | 
			
		||||
static int thread_reset_raised();
 | 
			
		||||
 | 
			
		||||
static int thread_no_ensure _((void));
 | 
			
		||||
 | 
			
		||||
static VALUE exception_error;
 | 
			
		||||
static VALUE sysstack_error;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3310,7 +3303,7 @@ rb_eval(self, n)
 | 
			
		|||
	    result = rb_eval(self, node->nd_head);
 | 
			
		||||
	}
 | 
			
		||||
	POP_TAG();
 | 
			
		||||
	if (node->nd_ensr) {
 | 
			
		||||
	if (node->nd_ensr && !thread_no_ensure()) {
 | 
			
		||||
	    VALUE retval = prot_tag->retval; /* save retval */
 | 
			
		||||
	    VALUE errinfo = ruby_errinfo;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4743,7 +4736,7 @@ rb_f_block_given_p()
 | 
			
		|||
    return Qfalse;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE rb_eThreadError;
 | 
			
		||||
VALUE rb_eThreadError;
 | 
			
		||||
 | 
			
		||||
NORETURN(static void proc_jump_error(int, VALUE));
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -5456,7 +5449,9 @@ rb_ensure(b_proc, data1, e_proc, data2)
 | 
			
		|||
    }
 | 
			
		||||
    POP_TAG();
 | 
			
		||||
    retval = prot_tag ? prot_tag->retval : Qnil;	/* save retval */
 | 
			
		||||
    if (!thread_no_ensure()) {
 | 
			
		||||
    (*e_proc)(data2);
 | 
			
		||||
    }
 | 
			
		||||
    if (prot_tag) return_value(retval);
 | 
			
		||||
    if (state) JUMP_TAG(state);
 | 
			
		||||
    return result;
 | 
			
		||||
| 
						 | 
				
			
			@ -9747,13 +9742,6 @@ VALUE rb_cThread;
 | 
			
		|||
 | 
			
		||||
extern VALUE rb_last_status;
 | 
			
		||||
 | 
			
		||||
enum thread_status {
 | 
			
		||||
    THREAD_TO_KILL,
 | 
			
		||||
    THREAD_RUNNABLE,
 | 
			
		||||
    THREAD_STOPPED,
 | 
			
		||||
    THREAD_KILLED,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define WAIT_FD		(1<<0)
 | 
			
		||||
#define WAIT_SELECT	(1<<1)
 | 
			
		||||
#define WAIT_TIME	(1<<2)
 | 
			
		||||
| 
						 | 
				
			
			@ -9773,70 +9761,10 @@ enum thread_status {
 | 
			
		|||
 | 
			
		||||
/* 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_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 END_FOREACH_FROM(f,x) } while (x != f)
 | 
			
		||||
| 
						 | 
				
			
			@ -9904,6 +9832,12 @@ thread_reset_raised()
 | 
			
		|||
    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 VALUE run_trap_eval _((VALUE));
 | 
			
		||||
| 
						 | 
				
			
			@ -10034,6 +9968,7 @@ thread_mark(th)
 | 
			
		|||
    rb_gc_mark(th->last_match);
 | 
			
		||||
    rb_mark_tbl(th->locals);
 | 
			
		||||
    rb_gc_mark(th->thgroup);
 | 
			
		||||
    rb_gc_mark_maybe(th->sandbox);
 | 
			
		||||
 | 
			
		||||
    /* mark data in copied stack */
 | 
			
		||||
    if (th == curr_thread) return;
 | 
			
		||||
| 
						 | 
				
			
			@ -10238,6 +10173,10 @@ rb_thread_save_context(th)
 | 
			
		|||
    th->safe = ruby_safe_level;
 | 
			
		||||
 | 
			
		||||
    th->node = ruby_current_node;
 | 
			
		||||
    if (ruby_sandbox_save != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      ruby_sandbox_save(th);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
| 
						 | 
				
			
			@ -10295,6 +10234,10 @@ rb_thread_restore_context_0(rb_thread_t th, int exit, void *vp)
 | 
			
		|||
    static VALUE tval;
 | 
			
		||||
 | 
			
		||||
    rb_trap_immediate = 0;	/* inhibit interrupts from here */
 | 
			
		||||
    if (ruby_sandbox_restore != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      ruby_sandbox_restore(th);
 | 
			
		||||
    }
 | 
			
		||||
    ruby_frame = th->frame;
 | 
			
		||||
    ruby_scope = th->scope;
 | 
			
		||||
    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:
 | 
			
		||||
 *     thr.exit        => thr or nil
 | 
			
		||||
 *     thr.kill        => thr or nil
 | 
			
		||||
 *     thr.terminate   => thr or nil
 | 
			
		||||
 *     thr.exit        => thr
 | 
			
		||||
 *     thr.kill        => thr
 | 
			
		||||
 *     thr.terminate   => thr
 | 
			
		||||
 *  
 | 
			
		||||
 *  Terminates <i>thr</i> and schedules another thread to be run. If this thread
 | 
			
		||||
 *  is already marked to be killed, <code>exit</code> returns the
 | 
			
		||||
 *  <code>Thread</code>. If this is the main thread, or the last thread, exits
 | 
			
		||||
 *  the process.
 | 
			
		||||
 *  Terminates <i>thr</i> 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
VALUE
 | 
			
		||||
| 
						 | 
				
			
			@ -11250,20 +11211,33 @@ rb_thread_kill(thread)
 | 
			
		|||
{
 | 
			
		||||
    rb_thread_t th = rb_thread_check(thread);
 | 
			
		||||
 | 
			
		||||
    if (th != curr_thread && th->safe < 4) {
 | 
			
		||||
	rb_secure(4);
 | 
			
		||||
    }
 | 
			
		||||
    if (th->status == THREAD_TO_KILL || th->status == THREAD_KILLED)
 | 
			
		||||
    kill_thread(th, 0);
 | 
			
		||||
	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:
 | 
			
		||||
 *     Thread.kill(thread)   => thread
 | 
			
		||||
| 
						 | 
				
			
			@ -11658,6 +11632,11 @@ rb_thread_group(thread)
 | 
			
		|||
    th->thgroup = thgroup_default;\
 | 
			
		||||
    th->locals = 0;\
 | 
			
		||||
    th->thread = 0;\
 | 
			
		||||
    if (curr_thread == 0) {\
 | 
			
		||||
      th->sandbox = Qnil;\
 | 
			
		||||
    } else {\
 | 
			
		||||
      th->sandbox = curr_thread->sandbox;\
 | 
			
		||||
    }\
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
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, "terminate", 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, "status", rb_thread_status, 0);
 | 
			
		||||
    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));
 | 
			
		||||
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)
 | 
			
		||||
}  /* extern "C" { */
 | 
			
		||||
#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_eSecurityError;
 | 
			
		||||
RUBY_EXTERN VALUE rb_eSystemCallError;
 | 
			
		||||
RUBY_EXTERN VALUE rb_eThreadError;
 | 
			
		||||
RUBY_EXTERN VALUE rb_eTypeError;
 | 
			
		||||
RUBY_EXTERN VALUE rb_eZeroDivError;
 | 
			
		||||
RUBY_EXTERN VALUE rb_eNotImpError;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue