Skip to content

Commit

Permalink
Detect recursive WAITs
Browse files Browse the repository at this point in the history
Recursive waits cause subtle problems that are hard to trouble shoot.
Throw an error to make it evident.
  • Loading branch information
zsx committed Jun 19, 2014
1 parent 56c2cc0 commit a9e8dde
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/boot/errors.r
Expand Up @@ -119,6 +119,8 @@ Script: [
parse-command: [{PARSE - command cannot be used as variable:} :arg1]
parse-series: [{PARSE - input must be a series:} :arg1]

recursive-wait: {recursive calls to WAIT}

; bad-prompt: [{Error executing prompt block}]
; bad-port-action: [{Cannot use} :arg1 {on this type port}]
; face-error: [{Invalid graphics face object}]
Expand Down
27 changes: 23 additions & 4 deletions src/core/n-io.c
Expand Up @@ -31,6 +31,8 @@

//#define HELPER

static int waited = 0; //for recursive WAIT detection


/** Helper Functions **************************************************/

Expand Down Expand Up @@ -309,7 +311,6 @@ static REBSER *Read_All_File(char *fname)
}
#endif


/***********************************************************************
**
*/ REBNATIVE(wait)
Expand All @@ -321,6 +322,12 @@ static REBSER *Read_All_File(char *fname)
REBSER *ports = 0;
REBINT n = 0;

if (waited != 0) {
Trap0(RE_RECURSIVE_WAIT);
}

++ waited;

SET_NONE(D_RET);

if (IS_BLOCK(val)) {
Expand All @@ -332,7 +339,10 @@ static REBSER *Read_All_File(char *fname)
if (IS_INTEGER(val) || IS_DECIMAL(val)) break;
}
if (IS_END(val)) {
if (n == 0) return R_NONE; // has no pending ports!
if (n == 0) { // has no pending ports!
--waited;
return R_NONE;
}
// SET_NONE(val); // no timeout -- BUG: unterminated block in GC
}
}
Expand All @@ -353,7 +363,10 @@ static REBSER *Read_All_File(char *fname)
break;

case REB_PORT:
if (!Pending_Port(val)) return R_NONE;
if (!Pending_Port(val)) {
-- waited;
return R_NONE;
}
ports = Make_Block(1);
Append_Val(ports, val);
// fall thru...
Expand All @@ -373,9 +386,13 @@ static REBSER *Read_All_File(char *fname)
// Process port events [stack-move]:
if (!Wait_Ports(ports, timeout)) {
Sieve_Ports(NULL); /* just reset the waked list */
-- waited;
return R_NONE;
}
if (!ports) {
-- waited;
return R_NONE;
}
if (!ports) return R_NONE;
DS_RELOAD(ds);

// Determine what port(s) waked us:
Expand All @@ -387,6 +404,8 @@ static REBSER *Read_All_File(char *fname)
else SET_NONE(D_RET);
}

-- waited;

return R_RET;
}

Expand Down

0 comments on commit a9e8dde

Please sign in to comment.