--- a/Process.st Thu Dec 07 22:24:46 1995 +0100
+++ b/Process.st Thu Dec 07 22:32:39 1995 +0100
@@ -11,10 +11,9 @@
"
Link subclass:#Process
- instanceVariableNames:'id prio state startBlock name
- restartable interruptActions
- exitActions suspendSemaphore
- singleStepping emergencySignalHandler'
+ instanceVariableNames:'id prio state startBlock name restartable interruptActions
+ exitActions suspendSemaphore singleStepping
+ emergencySignalHandler'
classVariableNames:'TerminateSignal CoughtSignals'
poolDictionaries:''
category:'Kernel-Processes'
@@ -36,10 +35,6 @@
"
!
-version
- ^ '$Header: /cvs/stx/stx/libbasic/Process.st,v 1.35 1995-11-13 09:08:17 stefan Exp $'
-!
-
documentation
"
Instances of Process represent lightweight smalltalk processes
@@ -203,6 +198,16 @@
]
! !
+!Process class methodsFor:'instance creation'!
+
+for:aBlock priority:aPrio
+ "create a new (unscheduled) process which will execute aBlock at
+ a given priority, once scheduled. The process will start execution once
+ it gets a #resume-message."
+
+ ^ self new for:aBlock priority:aPrio
+! !
+
!Process class methodsFor:'Signal constants'!
terminateSignal
@@ -211,14 +216,302 @@
^ TerminateSignal
! !
-!Process class methodsFor:'instance creation'!
+!Process methodsFor:'accessing'!
+
+changePriority:aNumber
+ "same as priority:, but returns the old priority.
+ (cannot do this in priority: for ST-80 compatibility)"
+
+ |oldPrio|
+
+ oldPrio := prio.
+ Processor changePriority:aNumber for:self.
+ ^ oldPrio
+!
+
+emergencySignalHandler
+ "return the emergencySignalHandler block.
+ See Signal>>documentation for more info."
+
+ ^ emergencySignalHandler
+!
+
+emergencySignalHandler:aOneArgBlock
+ "set the emergencySignalHandler block.
+ See Signal>>documentation for more info."
+
+ emergencySignalHandler := aOneArgBlock
+!
+
+exitAction:aBlock
+ "add aBlock to the processes exit actions.
+ This will be evaluated right before the process dies."
+
+ exitActions isNil ifTrue:[
+ exitActions := OrderedCollection new
+ ].
+ exitActions add:aBlock
+!
+
+id
+ "return the processes id"
+
+ ^ id
+!
+
+isDead
+ "return true, if the receiver has already terminated"
+
+ ^ state == #dead
+!
+
+isRestartable
+ "return true, iff the receiver is restartable"
+
+ ^ restartable
+!
+
+isSingleStepping
+ ^ singleStepping
+!
+
+maximumStackSize
+ "returns the processes stack limit - i.e. the process will be
+ interrupted with a recursionSignal-raise, if it ever
+ needs more stack (in bytes) than this number"
+
+%{ /* NOCONTEXT */
+ extern int __threadMaxStackSize();
+ OBJ i;
+
+ if (__isSmallInteger(i = _INST(id))) {
+ RETURN( _MKSMALLINT(__threadMaxStackSize(_intVal(i))) );
+ }
+%}.
+ ^ nil
+!
+
+name
+ "return the processes name"
+
+ ^ name
+!
+
+name:aString
+ "set the processes name"
+
+ name := aString
+!
+
+nameOrId
+ "return a string to identify the process - either name or id"
+
+ name notNil ifTrue:[^ name].
+ ^ id printString
+!
+
+priority
+ "return the receivers priority"
+
+ ^ prio
+!
+
+priority:aNumber
+ "set my priority"
+
+ Processor changePriority:aNumber for:self.
+!
+
+restartable:aBoolean
+ "set/clear, the restartable flag.
+ Restartable processes will automatically be restarted by the
+ ProcessorScheduler upon image restart. Others have to be restarted
+ manually."
+
+ startBlock isNil ifTrue:[
+ self error:'cannot be made restartable when already started'.
+ ^ self
+ ].
+ restartable := aBoolean
+!
+
+setMaximumStackSize:limit
+ "sets the processes stack limit - i.e. the process will be
+ interrupted with a recursionSignal-raise, if it ever
+ needs more stack (in bytes) than this number.
+ Returns the old value."
+
+%{ /* NOCONTEXT */
+ extern int __threadSetMaxStackSize();
+ OBJ i;
+
+ if (__isSmallInteger(i = _INST(id))
+ && __isSmallInteger(limit) ) {
+ RETURN ( _MKSMALLINT(__threadSetMaxStackSize(_intVal(i), _intVal(limit))) );
+ }
+%}.
+ ^ nil
+!
+
+singleStep:aBoolean
+ singleStepping := aBoolean
+!
+
+startBlock
+ "return the processes startup-block"
+
+ ^ startBlock
+!
-for:aBlock priority:aPrio
- "create a new (unscheduled) process which will execute aBlock at
- a given priority, once scheduled. The process will start execution once
- it gets a #resume-message."
+state
+ "return a symbol describing the processes state"
+
+ ^ state
+!
+
+state:aSymbol
+ "set the state - only to be used from scheduler"
+
+ state := aSymbol
+!
+
+suspendedContext
+ "return the processes suspended context
+ - this is the context from which a process switch into the scheduler
+ or another process occured.
+ Typically, only the debugger is interrested in this one."
+
+%{ /* NOCONTEXT */
+ extern OBJ __threadContext();
+ OBJ i;
+
+ if (__isSmallInteger(i = _INST(id))) {
+ RETURN (__threadContext(_intVal(i)));
+ }
+%}.
+ ^ nil
+! !
+
+!Process methodsFor:'interrupts'!
+
+interrupt
+ "evaluate my interrupt-actions
+ the process will go back to where it got interrupted
+ after doing this.
+ "
+ |action|
+
+ [interruptActions notNil and:[interruptActions notEmpty]] whileTrue:[
+ action := interruptActions removeFirst.
+ action value
+ ].
+ interruptActions := nil
+!
+
+interruptWith:aBlock
+ "interrupt the receiver and make it evaluate aBlock.
+ If the receiver is currently suspended, the block will be remembered
+ to be evaluated once the receiver wakes up."
+
+ self uninterruptablyDo:[
+ interruptActions isNil ifTrue:[
+ interruptActions := OrderedCollection with:aBlock.
+ ] ifFalse:[
+ interruptActions addLast:aBlock.
+ ].
+ ].
+ Processor scheduleForInterrupt:self.
+! !
+
+!Process methodsFor:'monitoring'!
+
+numberOfStackBoundaryHits
+ "internal monitoring only - will vanish"
+
+%{ /* NOCONTEXT */
+ extern int __threadNumberOfStackBoundaryHits();
+ int n;
+ OBJ i;
- ^ self new for:aBlock priority:aPrio
+ if (__isSmallInteger(i = _INST(id))) {
+ n = __threadNumberOfStackBoundaryHits(_intVal(i));
+ n &= 0x3FFFFFFF;
+ RETURN( _MKSMALLINT(n) );
+ }
+%}.
+ ^ nil
+!
+
+numberOfStackSegments
+ "return the processes number of stack segments currently used.
+ This method is for monitoring purposes only - it may vanish."
+
+%{ /* NOCONTEXT */
+ extern int __threadTotalStackSize();
+ OBJ i;
+
+ if (__isSmallInteger(i = _INST(id))) {
+ RETURN( _MKSMALLINT(__threadStackSegments(_intVal(i))) );
+ }
+%}.
+ ^ nil
+!
+
+totalStackSize
+ "return the processes maximum used stack size.
+ This method is for monitoring purposes only - it may vanish."
+
+%{ /* NOCONTEXT */
+ extern int __threadTotalStackSize();
+ OBJ i;
+
+ if (__isSmallInteger(i = _INST(id))) {
+ RETURN( _MKSMALLINT(__threadTotalStackSize(_intVal(i))) );
+ }
+%}.
+ ^ nil
+!
+
+usedStackSize
+ "Return the processes current stack size.
+ This method is for monitoring purposes only - it may vanish."
+
+%{ /* NOCONTEXT */
+ extern int __threadUsedStackSize();
+ OBJ i;
+
+ if (__isSmallInteger(i = _INST(id))) {
+ RETURN( _MKSMALLINT(__threadUsedStackSize(_intVal(i))) );
+ }
+%}.
+ ^ nil
+!
+
+vmTrace:aBoolean
+ "turn on/off VM message tracing for the receiver.
+ This is meant for ST/X debugging, and may vanish.
+ Expect lots of output, once this is turned on."
+
+%{ /* NOCONTEXT */
+ OBJ i;
+
+ if (__isSmallInteger(i = _INST(id))) {
+ __threadTracing(_intVal(i), aBoolean);
+ }
+%}.
+! !
+
+!Process methodsFor:'printing & storing'!
+
+printOn:aStream
+ "a little more info in my printed representation"
+
+ aStream nextPutAll:state article;
+ space;
+ nextPutAll:state;
+ nextPutAll:' Process (';
+ nextPutAll:self nameOrId;
+ nextPutAll:')'
! !
!Process methodsFor:'private'!
@@ -254,262 +547,15 @@
]
! !
-!Process methodsFor:'accessing'!
-
-state
- "return a symbol describing the processes state"
-
- ^ state
-!
-
-state:aSymbol
- "set the state - only to be used from scheduler"
-
- state := aSymbol
-!
-
-isDead
- "return true, if the receiver has already terminated"
-
- ^ state == #dead
-!
-
-startBlock
- "return the processes startup-block"
-
- ^ startBlock
-!
-
-emergencySignalHandler:aOneArgBlock
- "set the emergencySignalHandler block.
- See Signal>>documentation for more info."
-
- emergencySignalHandler := aOneArgBlock
-!
-
-emergencySignalHandler
- "return the emergencySignalHandler block.
- See Signal>>documentation for more info."
-
- ^ emergencySignalHandler
-!
-
-priority
- "return the receivers priority"
-
- ^ prio
-!
-
-priority:aNumber
- "set my priority"
-
- Processor changePriority:aNumber for:self.
-!
-
-isRestartable
- "return true, iff the receiver is restartable"
-
- ^ restartable
-!
-
-restartable:aBoolean
- "set/clear, the restartable flag.
- Restartable processes will automatically be restarted by the
- ProcessorScheduler upon image restart. Others have to be restarted
- manually."
-
- startBlock isNil ifTrue:[
- self error:'cannot be made restartable when already started'.
- ^ self
- ].
- restartable := aBoolean
-!
-
-changePriority:aNumber
- "same as priority:, but returns the old priority.
- (cannot do this in priority: for ST-80 compatibility)"
-
- |oldPrio|
-
- oldPrio := prio.
- Processor changePriority:aNumber for:self.
- ^ oldPrio
-!
-
-isSingleStepping
- ^ singleStepping
-!
-
-singleStep:aBoolean
- singleStepping := aBoolean
-!
-
-id
- "return the processes id"
-
- ^ id
-!
-
-name
- "return the processes name"
-
- ^ name
-!
-
-name:aString
- "set the processes name"
-
- name := aString
-!
-
-nameOrId
- "return a string to identify the process - either name or id"
-
- name notNil ifTrue:[^ name].
- ^ id printString
-!
-
-exitAction:aBlock
- "add aBlock to the processes exit actions.
- This will be evaluated right before the process dies."
-
- exitActions isNil ifTrue:[
- exitActions := OrderedCollection new
- ].
- exitActions add:aBlock
-!
+!Process methodsFor:'private scheduler access'!
-suspendedContext
- "return the processes suspended context
- - this is the context from which a process switch into the scheduler
- or another process occured.
- Typically, only the debugger is interrested in this one."
-
-%{ /* NOCONTEXT */
- extern OBJ __threadContext();
- OBJ i;
-
- if (__isSmallInteger(i = _INST(id))) {
- RETURN (__threadContext(_intVal(i)));
- }
-%}.
- ^ nil
-!
-
-maximumStackSize
- "returns the processes stack limit - i.e. the process will be
- interrupted with a recursionSignal-raise, if it ever
- needs more stack (in bytes) than this number"
-
-%{ /* NOCONTEXT */
- extern int __threadMaxStackSize();
- OBJ i;
-
- if (__isSmallInteger(i = _INST(id))) {
- RETURN( _MKSMALLINT(__threadMaxStackSize(_intVal(i))) );
- }
-%}.
- ^ nil
-!
-
-setMaximumStackSize:limit
- "sets the processes stack limit - i.e. the process will be
- interrupted with a recursionSignal-raise, if it ever
- needs more stack (in bytes) than this number.
- Returns the old value."
-
-%{ /* NOCONTEXT */
- extern int __threadSetMaxStackSize();
- OBJ i;
-
- if (__isSmallInteger(i = _INST(id))
- && __isSmallInteger(limit) ) {
- RETURN ( _MKSMALLINT(__threadSetMaxStackSize(_intVal(i), _intVal(limit))) );
- }
-%}.
- ^ nil
-! !
-
-!Process methodsFor:'monitoring'!
-
-vmTrace:aBoolean
- "turn on/off VM message tracing for the receiver.
- This is meant for ST/X debugging, and may vanish.
- Expect lots of output, once this is turned on."
-
-%{ /* NOCONTEXT */
- OBJ i;
+setId:idNumber state:stateSymbol
+ "set id and state - not for public use"
- if (__isSmallInteger(i = _INST(id))) {
- __threadTracing(_intVal(i), aBoolean);
- }
-%}.
-!
-
-usedStackSize
- "Return the processes current stack size.
- This method is for monitoring purposes only - it may vanish."
-
-%{ /* NOCONTEXT */
- extern int __threadUsedStackSize();
- OBJ i;
-
- if (__isSmallInteger(i = _INST(id))) {
- RETURN( _MKSMALLINT(__threadUsedStackSize(_intVal(i))) );
- }
-%}.
- ^ nil
-!
-
-totalStackSize
- "return the processes maximum used stack size.
- This method is for monitoring purposes only - it may vanish."
-
-%{ /* NOCONTEXT */
- extern int __threadTotalStackSize();
- OBJ i;
-
- if (__isSmallInteger(i = _INST(id))) {
- RETURN( _MKSMALLINT(__threadTotalStackSize(_intVal(i))) );
- }
-%}.
- ^ nil
+ id := idNumber.
+ state := stateSymbol.
!
-numberOfStackSegments
- "return the processes number of stack segments currently used.
- This method is for monitoring purposes only - it may vanish."
-
-%{ /* NOCONTEXT */
- extern int __threadTotalStackSize();
- OBJ i;
-
- if (__isSmallInteger(i = _INST(id))) {
- RETURN( _MKSMALLINT(__threadStackSegments(_intVal(i))) );
- }
-%}.
- ^ nil
-!
-
-numberOfStackBoundaryHits
- "internal monitoring only - will vanish"
-
-%{ /* NOCONTEXT */
- extern int __threadNumberOfStackBoundaryHits();
- int n;
- OBJ i;
-
- if (__isSmallInteger(i = _INST(id))) {
- n = __threadNumberOfStackBoundaryHits(_intVal(i));
- n &= 0x3FFFFFFF;
- RETURN( _MKSMALLINT(n) );
- }
-%}.
- ^ nil
-! !
-
-!Process methodsFor:'private scheduler access'!
-
setPriority:aNumber
"set priority without telling processor - not for public use"
@@ -528,17 +574,124 @@
setStateTo:newState if:oldState1 or:oldState2
(state == oldState1 or:[state == oldState2]) ifTrue:[state := newState]
+! !
+
+!Process methodsFor:'special'!
+
+trapRestrictedMethods:trap
+ "Allow/deny the execution of restricted methods.
+ Process specific method restriction is not implemented yet, so this call is
+ redirected to ObjectMemory and causes a system wide restriction.
+
+ Notice: method restriction is a nonstandard feature, not supported
+ by other smalltalk implementations and not specified in the ANSI spec.
+ This is EXPERIMENTAL - and being evaluated for usability.
+ It may change or even vanish (if it shows to be not useful)."
+
+ ^ObjectMemory trapRestrictedMethods:trap
+
+ "
+ Processor activeProcess trapRestrictedMethods:true
+ Processor activeProcess trapRestrictedMethods:false
+ "
+
+ "Created: 8.11.1995 / 19:45:04 / stefan"
+!
+
+uninterruptablyDo:aBlock
+ "execute aBlock with interrupts blocked.
+ This does not prevent preemption by a higher priority processes
+ if any becomes runnable due to the evaluation of aBlock
+ (i.e. if a semaphore is signalled there)."
+
+ |wasBlocked|
+
+ "we must keep track of blocking-state if this is called nested"
+
+ wasBlocked := OperatingSystem blockInterrupts.
+ ^ aBlock valueNowOrOnUnwindDo:[
+ wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
+ 0 "stc hint"
+ ]
!
-setId:idNumber state:stateSymbol
- "set id and state - not for public use"
+waitUntilSuspended
+ "wait until the receiver is suspended."
+
+ |wasBlocked|
+
+ wasBlocked := OperatingSystem blockInterrupts.
+ suspendSemaphore isNil ifTrue:[suspendSemaphore := Semaphore new].
+ suspendSemaphore wait
+ wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
+!
+
+waitUntilTerminated
+ "wait until the receiver is terminated.
+ This method allows another process to wait till the receiver finishes."
+
+ |wasBlocked sema|
+
+ wasBlocked := OperatingSystem blockInterrupts.
+ sema := Semaphore new.
+ self exitAction:[sema signal].
+ sema wait.
+ wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
+!
+
+withLowerPriorityDo:aBlock
+ "execute aBlock at a lower priority. This can be used to perform
+ time-consuming operations at a more user-friendly priority."
- id := idNumber.
- state := stateSymbol.
+ ^ self withPriority:(prio - 1) do:aBlock
+
+ "
+ Processor activeProcess withLowerPriorityDo:[3000 factorial]
+ "
+!
+
+withPriority:aPrio do:aBlock
+ "execute aBlock at another priority. This can be used to perform
+ time-consuming operations at a more user-friendly priority,
+ or some critical action at a higher priority. Do not use too high
+ of a priority to avoid locking up the system (event processing takes place
+ at 24)"
+
+ |oldprio|
+
+ oldprio := prio.
+ self priority:aPrio.
+
+ ^ aBlock valueNowOrOnUnwindDo:[
+ self priority:oldprio
+ ]
+
+ "
+ Processor activeProcess withPriority:7 do:[3000 factorial]
+ "
+ "be careful - even ^C wont work until done:
+ Processor activeProcess withPriority:25 do:[3000 factorial]
+ "
! !
!Process methodsFor:'startup '!
+restart
+ "restart the process from the beginning.
+ This is sent by the ProcessorScheduler to all restartable processes."
+
+"/ ('restart process ' , id printString) errorPrintNL.
+
+ (Processor newProcessFor:self withId:id) ifFalse:[
+ "for some reason, the Processor was unable to create
+ a VM process for me ...."
+
+ ('process ' , id printString , ' failed to restart.') errorPrintNL.
+ ^ nil
+ ].
+ self resume
+!
+
start
"start the process - this is sent by the VM to the process to get
the process up and running.
@@ -565,26 +718,22 @@
"is this artificial restriction useful ?"
self error:'a process cannot be started twice'
]
-!
-
-restart
- "restart the process from the beginning.
- This is sent by the ProcessorScheduler to all restartable processes."
-
-"/ ('restart process ' , id printString) errorPrintNL.
-
- (Processor newProcessFor:self withId:id) ifFalse:[
- "for some reason, the Processor was unable to create
- a VM process for me ...."
-
- ('process ' , id printString , ' failed to restart.') errorPrintNL.
- ^ nil
- ].
- self resume
! !
!Process methodsFor:'suspend / resume'!
+resume
+ "resume the receiver process"
+
+ Processor resume:self
+!
+
+resumeForSingleSend
+ "resume the receiver process, but only let it execute a single send."
+
+ Processor resumeForSingleSend:self
+!
+
stop
"suspend the receiver process - will continue to run when a resume is sent.
A stopped process will not be resumed for interrupt processing."
@@ -602,18 +751,6 @@
Processor suspend:self
!
-resume
- "resume the receiver process"
-
- Processor resume:self
-!
-
-resumeForSingleSend
- "resume the receiver process, but only let it execute a single send."
-
- Processor resumeForSingleSend:self
-!
-
terminate
"terminate the receiver process. Termination is done by raising
the terminateSignal in the receiver process, which can be cought.
@@ -649,144 +786,9 @@
Processor terminateNoSignal:self
! !
-!Process methodsFor:'interrupts'!
-
-interruptWith:aBlock
- "interrupt the receiver and make it evaluate aBlock.
- If the receiver is currently suspended, the block will be remembered
- to be evaluated once the receiver wakes up."
-
- self uninterruptablyDo:[
- interruptActions isNil ifTrue:[
- interruptActions := OrderedCollection with:aBlock.
- ] ifFalse:[
- interruptActions addLast:aBlock.
- ].
- ].
- Processor scheduleForInterrupt:self.
-!
-
-interrupt
- "evaluate my interrupt-actions
- the process will go back to where it got interrupted
- after doing this.
- "
- |action|
-
- [interruptActions notNil and:[interruptActions notEmpty]] whileTrue:[
- action := interruptActions removeFirst.
- action value
- ].
- interruptActions := nil
-! !
-
-!Process methodsFor:'special'!
-
-withPriority:aPrio do:aBlock
- "execute aBlock at another priority. This can be used to perform
- time-consuming operations at a more user-friendly priority,
- or some critical action at a higher priority. Do not use too high
- of a priority to avoid locking up the system (event processing takes place
- at 24)"
-
- |oldprio|
-
- oldprio := prio.
- self priority:aPrio.
-
- ^ aBlock valueNowOrOnUnwindDo:[
- self priority:oldprio
- ]
-
- "
- Processor activeProcess withPriority:7 do:[3000 factorial]
- "
- "be careful - even ^C wont work until done:
- Processor activeProcess withPriority:25 do:[3000 factorial]
- "
-!
-
-withLowerPriorityDo:aBlock
- "execute aBlock at a lower priority. This can be used to perform
- time-consuming operations at a more user-friendly priority."
-
- ^ self withPriority:(prio - 1) do:aBlock
-
- "
- Processor activeProcess withLowerPriorityDo:[3000 factorial]
- "
-!
+!Process class methodsFor:'documentation'!
-uninterruptablyDo:aBlock
- "execute aBlock with interrupts blocked.
- This does not prevent preemption by a higher priority processes
- if any becomes runnable due to the evaluation of aBlock
- (i.e. if a semaphore is signalled there)."
-
- |wasBlocked|
-
- "we must keep track of blocking-state if this is called nested"
-
- wasBlocked := OperatingSystem blockInterrupts.
- ^ aBlock valueNowOrOnUnwindDo:[
- wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
- 0 "stc hint"
- ]
-!
-
-waitUntilTerminated
- "wait until the receiver is terminated.
- This method allows another process to wait till the receiver finishes."
-
- |wasBlocked sema|
-
- wasBlocked := OperatingSystem blockInterrupts.
- sema := Semaphore new.
- self exitAction:[sema signal].
- sema wait.
- wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
-!
-
-waitUntilSuspended
- "wait until the receiver is suspended."
-
- |wasBlocked|
-
- wasBlocked := OperatingSystem blockInterrupts.
- suspendSemaphore isNil ifTrue:[suspendSemaphore := Semaphore new].
- suspendSemaphore wait
- wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
-!
-
-trapRestrictedMethods:trap
- "Allow/deny the execution of restricted methods.
- Process specific method restriction is not implemented yet, so this call is
- redirected to ObjectMemory and causes a system wide restriction.
-
- Notice: method restriction is a nonstandard feature, not supported
- by other smalltalk implementations and not specified in the ANSI spec.
- This is EXPERIMENTAL - and being evaluated for usability.
- It may change or even vanish (if it shows to be not useful)."
-
- ^ObjectMemory trapRestrictedMethods:trap
-
- "
- Processor activeProcess trapRestrictedMethods:true
- Processor activeProcess trapRestrictedMethods:false
- "
-
- "Created: 8.11.1995 / 19:45:04 / stefan"
+version
+ ^ '$Header: /cvs/stx/stx/libbasic/Process.st,v 1.36 1995-12-07 21:29:26 cg Exp $'
! !
-
-!Process methodsFor:'printing & storing'!
-
-printOn:aStream
- "a little more info in my printed representation"
-
- aStream nextPutAll:state article;
- space;
- nextPutAll:state;
- nextPutAll:' Process (';
- nextPutAll:self nameOrId;
- nextPutAll:')'
-! !
+Process initialize!