struct Map_ id;
MUTEX_TYPE mutex;
struct Vector_ child;
+ struct Vector_ child2;
struct Vector_ reserved;
struct Map_ pass_map;
struct Vector_ pass;
ANN void free_object(MemPool p, const M_Object);
ANEW M_Object new_object(MemPool, const VM_Shred, const Type);
ANEW M_Object new_M_UGen(const struct Gwion_*);
+ANN void fork_clean(const VM_Shred, const Vector);
ANN ANEW M_Object new_array(MemPool, const Type t, const m_uint length);
ANEW M_Object new_string(MemPool, const VM_Shred, const m_str);
ANEW M_Object new_string2(const struct Gwion_*, const VM_Shred, const m_str);
ANEW M_Object gwion_new_string(const struct Gwion_*, const m_str);
ANEW M_Object new_shred(const VM_Shred, const m_bool);
ANN void fork_launch(const VM*, const M_Object, const m_uint);
-ANN void fork_clean(const VM *vm, const Vector v);
ANN void __release(const M_Object, const VM_Shred);
ANN void exception(const VM_Shred, const m_str);
ANN void broadcast(const M_Object);
}
ANN m_bool gwion_ini(const Gwion gwion, Arg* arg) {
- gwion->mp = mempool_ini((sizeof(VM_Shred) + SIZEOF_REG + SIZEOF_MEM) / SZ_INT);
+ gwion->mp = mempool_ini((sizeof(struct VM_Shred_) + SIZEOF_REG + SIZEOF_MEM));
gwion->st = new_symbol_table(gwion->mp, 65347);
gwion->vm = new_vm(gwion->mp, 1);
gwion->emit = new_emitter(gwion->mp);
vm->bbq->driver->run(vm, vm->bbq);
}
+ANN static void fork_clean2(const Vector v) {
+ for(m_uint i = 0; i < vector_size(v); ++i) {
+ VM* vm = (VM*)vector_at(v, i);
+ const Gwion gwion = vm->gwion;
+ free_vm(vm);
+ mp_free(gwion->mp, Gwion, gwion);
+ }
+ vector_release(v);
+}
+
ANN void gwion_end(const Gwion gwion) {
const VM_Code code = new_vm_code(gwion->mp, NULL, 0, ae_flag_builtin, "in code dtor");
gwion->vm->cleaner_shred = new_vm_shred(gwion->mp, code);
vm_add_shred(gwion->vm, gwion->vm->cleaner_shred);
MUTEX_LOCK(gwion->vm->shreduler->mutex);
if(gwion->data->child.ptr)
- fork_clean(gwion->vm, &gwion->data->child);
+ fork_clean(gwion->vm->cleaner_shred, &gwion->data->child);
+ if(gwion->data->child2.ptr)
+ fork_clean2(&gwion->data->child2);
MUTEX_UNLOCK(gwion->vm->shreduler->mutex);
free_env(gwion->env);
free_vm_shred(gwion->vm->cleaner_shred);
}
static DTOR(fork_dtor) {
- if(*(m_int*)(o->data + o_fork_done))
- vector_rem2(&FORK_ORIG(o)->gwion->data->child, (vtype)o);
THREAD_JOIN(FORK_THREAD(o));
- VM *vm = ME(o)->info->vm;
- free_vm(vm);
- mp_free(shred->info->mp, Gwion, vm->gwion);
+ if(*(m_int*)(o->data + o_fork_done)) {
+ vector_rem2(&FORK_ORIG(o)->gwion->data->child, (vtype)o);
+ vector_add(&FORK_ORIG(o)->gwion->data->child2, (vtype)ME(o)->info->vm);
+ } else exit(6);
}
static MFUN(fork_join) {
THREAD_RETURN(NULL);
}
-ANN void fork_clean(const VM *vm, const Vector v) {
- for(m_uint i = 0; i < vector_size(v); ++i) {
- const M_Object o = (M_Object)vector_at(v, i);
- THREAD_JOIN(FORK_THREAD(o));
- release(o, vm->cleaner_shred);
- }
- vector_release(v);
-}
-
-void fork_launch(const VM* vm, const M_Object o, const m_uint sz) {
+ANN void fork_launch(const VM* vm, const M_Object o, const m_uint sz) {
o->ref += 1;
- if(!vm->gwion->data->child.ptr)
+ if(!vm->gwion->data->child.ptr) {
vector_init(&vm->gwion->data->child);
+ vector_init(&vm->gwion->data->child2);
+ }
vector_add(&vm->gwion->data->child, (vtype)o);
FORK_ORIG(o) = (VM*)vm;
FORK_RETSIZE(o) = sz;
THREAD_CREATE(FORK_THREAD(o), fork_run, o);
}
+
+ANN void fork_clean(const VM_Shred shred, const Vector v) {
+ for(m_uint i = 0; i < vector_size(v); ++i) {
+ const M_Object o = (M_Object)vector_at(v, i);
+ THREAD_JOIN(FORK_THREAD(o));
+ release(o, shred);
+ }
+ vector_release(v);
+}
#include "nspc.h"
GWION_IMPORT(shred) {
const Type t_shred = gwi_mk_type(gwi, "Shred", SZ_INT, "Object");
arg_release(&arg);
if(ini > 0)
gwion_run(&gwion);
-#ifndef NDEBUG
gwion_end(&gwion);
-#else
- free_plug(&gwion);
-#endif
THREAD_RETURN(EXIT_SUCCESS);
}