mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* vm.c (ruby_vm_at_exit): new API. This enables extension libs to
hook a VM termination. Right now, because the VM we have is process global, most extensions do not deallocate resources and leave them to Operating System's reaping userland processes. But in a future we plan to have multiple VMs to run simultaneously in a single process (MVM project). At that stage we can no longer rely on OSes and have to manage every resources to be reclaimed properly. So it is. For a forward-compatibility reason this API is introduced now, encouraging you to be as gentle as you can for your resources; that is, tidy up your room. * include/ruby/vm.h: ditto. * vm_core.h (rb_vm_struct): new field. * vm.c (vm_init2): initialize above new field. * eval.c (ruby_cleanup): trigger those hooks. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30050 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
cf39e78e1f
commit
51da92ea12
5 changed files with 65 additions and 0 deletions
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
||||||
|
Thu Dec 2 19:58:24 2010 URABE Shyouhei <shyouhei@ruby-lang.org>
|
||||||
|
|
||||||
|
* vm.c (ruby_vm_at_exit): new API. This enables extension libs to
|
||||||
|
hook a VM termination. Right now, because the VM we have is
|
||||||
|
process global, most extensions do not deallocate resources and
|
||||||
|
leave them to Operating System's reaping userland processes. But
|
||||||
|
in a future we plan to have multiple VMs to run simultaneously in
|
||||||
|
a single process (MVM project). At that stage we can no longer
|
||||||
|
rely on OSes and have to manage every resources to be reclaimed
|
||||||
|
properly. So it is. For a forward-compatibility reason this API
|
||||||
|
is introduced now, encouraging you to be as gentle as you can for
|
||||||
|
your resources; that is, tidy up your room.
|
||||||
|
|
||||||
|
* include/ruby/vm.h: ditto.
|
||||||
|
|
||||||
|
* vm_core.h (rb_vm_struct): new field.
|
||||||
|
|
||||||
|
* vm.c (vm_init2): initialize above new field.
|
||||||
|
|
||||||
|
* eval.c (ruby_cleanup): trigger those hooks.
|
||||||
|
|
||||||
Thu Dec 2 17:00:44 2010 Tanaka Akira <akr@fsij.org>
|
Thu Dec 2 17:00:44 2010 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* bignum.c: parenthesize macro arguments.
|
* bignum.c: parenthesize macro arguments.
|
||||||
|
|
10
eval.c
10
eval.c
|
@ -129,6 +129,9 @@ ruby_cleanup(volatile int ex)
|
||||||
int nerr;
|
int nerr;
|
||||||
void rb_threadptr_interrupt(rb_thread_t *th);
|
void rb_threadptr_interrupt(rb_thread_t *th);
|
||||||
void rb_threadptr_check_signal(rb_thread_t *mth);
|
void rb_threadptr_check_signal(rb_thread_t *mth);
|
||||||
|
int i;
|
||||||
|
rb_vm_t *vm = GET_VM();
|
||||||
|
VALUE ary = (VALUE)&vm->at_exit;
|
||||||
|
|
||||||
rb_threadptr_interrupt(th);
|
rb_threadptr_interrupt(th);
|
||||||
rb_threadptr_check_signal(th);
|
rb_threadptr_check_signal(th);
|
||||||
|
@ -148,6 +151,13 @@ ruby_cleanup(volatile int ex)
|
||||||
}
|
}
|
||||||
POP_TAG();
|
POP_TAG();
|
||||||
|
|
||||||
|
/* at_exit functions called here; any other place more apropriate
|
||||||
|
* for this purpose? let me know if any. */
|
||||||
|
for (i=0; i<RARRAY_LEN(ary); i++) {
|
||||||
|
((void(*)(rb_vm_t*))RARRAY_PTR(ary)[i])(vm);
|
||||||
|
}
|
||||||
|
rb_ary_clear(ary);
|
||||||
|
|
||||||
errs[0] = th->errinfo;
|
errs[0] = th->errinfo;
|
||||||
PUSH_TAG();
|
PUSH_TAG();
|
||||||
if ((state = EXEC_TAG()) == 0) {
|
if ((state = EXEC_TAG()) == 0) {
|
||||||
|
|
|
@ -36,6 +36,24 @@ typedef struct rb_vm_struct ruby_vm_t;
|
||||||
/* core API */
|
/* core API */
|
||||||
int ruby_vm_destruct(ruby_vm_t *vm);
|
int ruby_vm_destruct(ruby_vm_t *vm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ruby_vm_at_exit registers a function _func_ to be invoked when a VM
|
||||||
|
* passed away. Functions registered this way runs in reverse order
|
||||||
|
* of registration, just like END {} block does. The difference is
|
||||||
|
* its timing to be triggered. ruby_vm_at_exit functions runs when a
|
||||||
|
* VM _passed_ _away_, while END {} blocks runs just _before_ a VM
|
||||||
|
* _is_ _passing_ _away_.
|
||||||
|
*
|
||||||
|
* You cannot register a function to another VM than where you are in.
|
||||||
|
* So where to register is intuitive, omitted. OTOH the argument
|
||||||
|
* _func_ cannot know which VM it is in because at the time of
|
||||||
|
* invocation, the VM has already died and there is no execution
|
||||||
|
* context. The VM itself is passed as the first argument to it.
|
||||||
|
*
|
||||||
|
* @param[in] func the function to register.
|
||||||
|
*/
|
||||||
|
void ruby_vm_at_exit(void(*func)(ruby_vm_t *));
|
||||||
|
|
||||||
#if defined __GNUC__ && __GNUC__ >= 4
|
#if defined __GNUC__ && __GNUC__ >= 4
|
||||||
#pragma GCC visibility pop
|
#pragma GCC visibility pop
|
||||||
#endif
|
#endif
|
||||||
|
|
10
vm.c
10
vm.c
|
@ -173,6 +173,14 @@ vm_get_ruby_level_caller_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* at exit */
|
||||||
|
|
||||||
|
void
|
||||||
|
ruby_vm_at_exit(void (*func)(rb_vm_t *))
|
||||||
|
{
|
||||||
|
rb_ary_push((VALUE)&GET_VM()->at_exit, (VALUE)func);
|
||||||
|
}
|
||||||
|
|
||||||
/* Env */
|
/* Env */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1572,6 +1580,8 @@ vm_init2(rb_vm_t *vm)
|
||||||
{
|
{
|
||||||
MEMZERO(vm, rb_vm_t, 1);
|
MEMZERO(vm, rb_vm_t, 1);
|
||||||
vm->src_encoding_index = -1;
|
vm->src_encoding_index = -1;
|
||||||
|
vm->at_exit.basic.flags = (T_ARRAY | RARRAY_EMBED_FLAG) & ~RARRAY_EMBED_LEN_MASK; /* len set 0 */
|
||||||
|
vm->at_exit.basic.klass = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Thread */
|
/* Thread */
|
||||||
|
|
|
@ -317,6 +317,12 @@ typedef struct rb_vm_struct {
|
||||||
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
|
#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
|
||||||
struct rb_objspace *objspace;
|
struct rb_objspace *objspace;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @shyouhei notes that this is not for storing normal Ruby
|
||||||
|
* objects so do *NOT* mark this when you GC.
|
||||||
|
*/
|
||||||
|
struct RArray at_exit;
|
||||||
} rb_vm_t;
|
} rb_vm_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
Loading…
Reference in a new issue