From 3c4bb2ba6c459ab629a03d55010d5cf0a9d867a0 Mon Sep 17 00:00:00 2001 From: snake5 Date: Sat, 13 Jun 2015 12:49:00 +0300 Subject: [PATCH] fixed 2 coroutine bugs: - abandoned coroutines do not properly free stack frames - abandoned coroutines trigger recursive state freeing --- ext/sgsapitest.c | 12 ++++++++++++ src/sgs_ctx.c | 7 +++++++ src/sgscript.h | 1 + tests/bug00028.sgs | 7 +++++++ 4 files changed, 27 insertions(+) create mode 100644 tests/bug00028.sgs diff --git a/ext/sgsapitest.c b/ext/sgsapitest.c index 52b7176..17a9e46 100644 --- a/ext/sgsapitest.c +++ b/ext/sgsapitest.c @@ -797,6 +797,17 @@ DEFINE_TEST( yield_resume ) destroy_context( C ); } +DEFINE_TEST( yield_abandon ) +{ + SGS_CTX = get_context(), *CF; + + CF = sgs_ForkState( C, 0 ); + const char* str = "yield();"; + atf_assert( sgs_ExecString( CF, str ) == SGS_SUCCESS ); + + destroy_context( C ); +} + int sm_tick_id = 0; int sm_resume_id = 0; static int sm_wait( SGS_CTX ) @@ -869,6 +880,7 @@ test_t all_tests[] = TST( native_obj_meta ), TST( fork_state ), TST( yield_resume ), + TST( yield_abandon ), TST( state_machine_core ), }; int all_tests_count(){ return sizeof(all_tests)/sizeof(test_t); } diff --git a/src/sgs_ctx.c b/src/sgs_ctx.c index 0c0b14c..4d1623c 100644 --- a/src/sgs_ctx.c +++ b/src/sgs_ctx.c @@ -134,6 +134,12 @@ static void ctx_destroy( SGS_CTX ) { SGS_SHCTX_USE; + if( C->state & SGS_STATE_DESTROYING ) + { + return; + } + C->state |= SGS_STATE_DESTROYING; + /* clear the stack */ while( C->stack_base != C->stack_top ) { @@ -160,6 +166,7 @@ static void ctx_destroy( SGS_CTX ) sgs_StackFrame* sf = C->sf_cached, *sfn; while( sf ) { + sgs_Release( C, &sf->func ); sfn = sf->cached; sgs_Dealloc( sf ); sf = sfn; diff --git a/src/sgscript.h b/src/sgscript.h index 46eba23..e17c77d 100644 --- a/src/sgscript.h +++ b/src/sgscript.h @@ -152,6 +152,7 @@ typedef SGSRESULT (*sgs_ScriptFSFunc) ( #define SGS_MUST_STOP (0x00020000 | SGS_HAS_ERRORS) #define SGS_SERIALIZE_MODE2 0x0004 #define SGS_STATE_PAUSED 0x0008 +#define SGS_STATE_DESTROYING 0x0010 /* Statistics / debugging */ diff --git a/tests/bug00028.sgs b/tests/bug00028.sgs new file mode 100644 index 0000000..88fa2e0 --- /dev/null +++ b/tests/bug00028.sgs @@ -0,0 +1,7 @@ +x = {}; +co = co_create(function(x) +{ + yield(); +}); +x.co = co; +co_resume( co, x );