enhanced unwind handling upon process termination
This commit is contained in:
parent
436babff3c
commit
a22f5ea0ab
@ -170,10 +170,20 @@
|
|||||||
^self atLevel: Log.INFO log: message.
|
^self atLevel: Log.INFO log: message.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#method log: message and: message2
|
||||||
|
{
|
||||||
|
^self atLevel: Log.INFO log: message and: message2.
|
||||||
|
}
|
||||||
|
|
||||||
#method logNl: message
|
#method logNl: message
|
||||||
{
|
{
|
||||||
^self atLevel: Log.INFO logNl: message.
|
^self atLevel: Log.INFO logNl: message.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#method logNl: message and: message2
|
||||||
|
{
|
||||||
|
^self atLevel: Log.INFO logNl: message and: message2.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#class Namespace(Set)
|
#class Namespace(Set)
|
||||||
|
@ -150,6 +150,7 @@
|
|||||||
## -------------------------------------------------------------------
|
## -------------------------------------------------------------------
|
||||||
|
|
||||||
| ctx stop |
|
| ctx stop |
|
||||||
|
|
||||||
ctx := self.
|
ctx := self.
|
||||||
stop := false.
|
stop := false.
|
||||||
[stop] whileFalse: [
|
[stop] whileFalse: [
|
||||||
|
@ -43,9 +43,38 @@
|
|||||||
self primitiveFailed
|
self primitiveFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#method _suspend
|
||||||
|
{
|
||||||
|
<primitive: #_process_suspend>
|
||||||
|
self primitiveFailed
|
||||||
|
}
|
||||||
|
|
||||||
#method terminate
|
#method terminate
|
||||||
{
|
{
|
||||||
##search from the top contextof the process down to intial_contextand find ensure blocks and execute them.
|
##search from the top contextof the process down to intial_contextand find ensure blocks and execute them.
|
||||||
|
## if a different process calls 'terminate' on a process,
|
||||||
|
## the ensureblock is not executed in the context of the
|
||||||
|
## process being terminated, but in the context of terminatig process.
|
||||||
|
##
|
||||||
|
## 1) process termianted by another process
|
||||||
|
## p := [
|
||||||
|
## [ 1 to: 10000 by: 1 do: [:ex | System logNl: i asString] ] ensure: [System logNl: 'ensured....']
|
||||||
|
## ] newProcess.
|
||||||
|
## p resume.
|
||||||
|
## p terminate.
|
||||||
|
##
|
||||||
|
## 2) process terminated by itself
|
||||||
|
## p := [
|
||||||
|
## [ Processor activeProcess terminate. ] ensure: [System logNl: 'ensured....']
|
||||||
|
## ] newProcess.
|
||||||
|
## p resume.
|
||||||
|
## p terminate.
|
||||||
|
## ----------------------------------------------------------------------------------------------------------
|
||||||
|
## the process must be frozen first. while unwinding is performed,
|
||||||
|
## the process must not be scheduled.
|
||||||
|
## ----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
(Processor activeProcess ~~ self) ifTrue: [ self _suspend ].
|
||||||
self.current_context unwindTo: self.initial_context return: nil.
|
self.current_context unwindTo: self.initial_context return: nil.
|
||||||
^self _terminate
|
^self _terminate
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,8 @@
|
|||||||
v1 := [
|
v1 := [
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
1 to: 10000 by: 1 do: [:i | System logNl: i asString. Processor sleepFor: 5. ]
|
##1 to: 20000 by: 1 do: [:i | System logNl: i asString. "Processor sleepFor: 1." ]
|
||||||
|
Processor activeProcess terminate.
|
||||||
] ensure: [ System logNl: '<<<PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP>>>' ].
|
] ensure: [ System logNl: '<<<PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP>>>' ].
|
||||||
|
|
||||||
] ensure: [ System logNl: '<<--------------------->>' ].
|
] ensure: [ System logNl: '<<--------------------->>' ].
|
||||||
@ -88,6 +89,7 @@
|
|||||||
|
|
||||||
System logNl: 'RESUMING v1'.
|
System logNl: 'RESUMING v1'.
|
||||||
v1 resume.
|
v1 resume.
|
||||||
|
Processor sleepFor: 1.
|
||||||
v1 terminate.
|
v1 terminate.
|
||||||
|
|
||||||
##[
|
##[
|
||||||
|
@ -97,6 +97,7 @@
|
|||||||
(stix)->active_method = (stix_oop_method_t)(stix)->active_context->origin->method_or_nargs; \
|
(stix)->active_method = (stix_oop_method_t)(stix)->active_context->origin->method_or_nargs; \
|
||||||
SET_ACTIVE_METHOD_CODE(stix); \
|
SET_ACTIVE_METHOD_CODE(stix); \
|
||||||
LOAD_ACTIVE_IP (stix); \
|
LOAD_ACTIVE_IP (stix); \
|
||||||
|
(stix)->processor->active->current_context = (stix)->active_context; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define FETCH_BYTE_CODE(stix) ((stix)->active_code[(stix)->ip++])
|
#define FETCH_BYTE_CODE(stix) ((stix)->active_code[(stix)->ip++])
|
||||||
@ -1234,14 +1235,19 @@ static int prim_log (stix_t* stix, stix_ooi_t nargs)
|
|||||||
else if (STIX_OBJ_GET_FLAGS_TYPE(msg) == STIX_OBJ_TYPE_OOP)
|
else if (STIX_OBJ_GET_FLAGS_TYPE(msg) == STIX_OBJ_TYPE_OOP)
|
||||||
{
|
{
|
||||||
/* visit only 1-level down into an array-like object */
|
/* visit only 1-level down into an array-like object */
|
||||||
stix_oop_t inner;
|
stix_oop_t inner, _class;
|
||||||
stix_oow_t i;
|
stix_oow_t i, spec;
|
||||||
|
|
||||||
if (STIX_CLASSOF(stix,msg) == stix->_association) goto dump_object;
|
_class = STIX_CLASSOF(stix, msg);
|
||||||
|
|
||||||
|
spec = STIX_OOP_TO_SMOOI(((stix_oop_class_t)_class)->spec);
|
||||||
|
if (STIX_CLASS_SPEC_NAMED_INSTVAR(spec) > 0 || !STIX_CLASS_SPEC_IS_INDEXED(spec)) goto dump_object;
|
||||||
|
|
||||||
for (i = 0; i < STIX_OBJ_GET_SIZE(msg); i++)
|
for (i = 0; i < STIX_OBJ_GET_SIZE(msg); i++)
|
||||||
{
|
{
|
||||||
inner = ((stix_oop_oop_t)msg)->slot[i];
|
inner = ((stix_oop_oop_t)msg)->slot[i];
|
||||||
|
|
||||||
|
if (i > 0) stix_logbfmt (stix, mask, " ");
|
||||||
if (STIX_OOP_IS_POINTER(inner) &&
|
if (STIX_OOP_IS_POINTER(inner) &&
|
||||||
STIX_OBJ_GET_FLAGS_TYPE(inner) == STIX_OBJ_TYPE_CHAR)
|
STIX_OBJ_GET_FLAGS_TYPE(inner) == STIX_OBJ_TYPE_CHAR)
|
||||||
{
|
{
|
||||||
@ -1869,6 +1875,20 @@ static int prim_process_yield (stix_t* stix, stix_ooi_t nargs)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int prim_process_suspend (stix_t* stix, stix_ooi_t nargs)
|
||||||
|
{
|
||||||
|
stix_oop_t rcv;
|
||||||
|
STIX_ASSERT (nargs == 0);
|
||||||
|
|
||||||
|
rcv = STIX_STACK_GET(stix, stix->sp);
|
||||||
|
if (STIX_CLASSOF(stix,rcv) != stix->_process) return 0;
|
||||||
|
|
||||||
|
suspend_process (stix, (stix_oop_process_t)rcv);
|
||||||
|
|
||||||
|
/* keep the receiver in the stack top */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int prim_semaphore_signal (stix_t* stix, stix_ooi_t nargs)
|
static int prim_semaphore_signal (stix_t* stix, stix_ooi_t nargs)
|
||||||
{
|
{
|
||||||
stix_oop_t rcv;
|
stix_oop_t rcv;
|
||||||
@ -2724,6 +2744,7 @@ static prim_t primitives[] =
|
|||||||
{ 0, 0, prim_process_resume, "_process_resume" },
|
{ 0, 0, prim_process_resume, "_process_resume" },
|
||||||
{ 0, 0, prim_process_terminate, "_process_terminate" },
|
{ 0, 0, prim_process_terminate, "_process_terminate" },
|
||||||
{ 0, 0, prim_process_yield, "_process_yield" },
|
{ 0, 0, prim_process_yield, "_process_yield" },
|
||||||
|
{ 0, 0, prim_process_suspend, "_process_suspend" },
|
||||||
{ 0, 0, prim_semaphore_signal, "_semaphore_signal" },
|
{ 0, 0, prim_semaphore_signal, "_semaphore_signal" },
|
||||||
{ 0, 0, prim_semaphore_wait, "_semaphore_wait" },
|
{ 0, 0, prim_semaphore_wait, "_semaphore_wait" },
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user