"====================================================================== | | Process Method Definitions | | $Revision: 1.7.5$ | $Date: 2000/05/28 16:56:52$ | $Author: pb$ | ======================================================================" "====================================================================== | | Copyright 1988-92, 1994-95, 1999, 2000 Free Software Foundation, Inc. | Written by Steve Byrne. | | This file is part of the GNU Smalltalk class library. | | The GNU Smalltalk class library is free software; you can redistribute it | and/or modify it under the terms of the GNU Lesser General Public License | as published by the Free Software Foundation; either version 2.1, or (at | your option) any later version. | | The GNU Smalltalk class library is distributed in the hope that it will be | useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser | General Public License for more details. | | You should have received a copy of the GNU Lesser General Public License | along with the GNU Smalltalk class library; see the file COPYING.LESSER. | If not, write to the Free Software Foundation, 59 Temple Place - Suite | 330, Boston, MA 02111-1307, USA. | ======================================================================" Link subclass: #Process instanceVariableNames: 'suspendedContext priority myList name exceptionHandlers' classVariableNames: '' poolDictionaries: '' category: 'Language-Processes' ! Process comment: 'I represent a unit of computation. My instances are independantly executable blocks that have a priority associated with them, and they can suspend themselves and resume themselves however they wish.' ! !Process class methodsFor: 'basic'! on: aBlockContext at: aPriority "Private - Create a process running aBlockContext at the given priority" ^self new onBlock: aBlockContext at: aPriority ! ! !Process methodsFor: 'basic'! lowerPriority "Lower a bit the priority of the receiver. A #lowerPriority will cancel a previous #raisePriority, and vice versa." self priority: self priority - 1! raisePriority "Raise a bit the priority of the receiver. A #lowerPriority will cancel a previous #raisePriority, and vice versa." self priority: self priority + 1! suspend "Do nothing if we're already suspended. Note that the blue book made suspend a primitive - but the real primitive is yielding control to another process. Suspending is nothing more than taking ourselves out of every scheduling list and THEN yield control to another process" self isSuspended ifTrue: [ ^nil ]. myList remove: self ifAbsent: [ ]. myList := nil. self yield ! terminate "Terminate the receiver - This is nothing more than prohibiting to resume the process, then suspending it." suspendedContext := nil. self suspend ! forceResume "Private - Force a resume of the process from whatever status it was in (even if it was waiting on a semaphore). This is BAD practice, it is present only for some future possibility." self isReady ifTrue: [ ^self ]. self isSuspended ifFalse: [ myList remove: self ifAbsent: [ ] ]. myList := Processor processesAt: self priority. myList addLast: self. self resume ! ! !Process methodsFor: 'printing'! printOn: aStream "Print a representation of the receiver on aStream" aStream print: self class; nextPut: $(; print: name; nextPutAll: ' at '; nextPutAll: (Processor priorityName: self priority); nextPut: $,. "The order here is important!" self isActive ifTrue: [ aStream nextPutAll: ' active)'. ^self ]. self isTerminated ifTrue: [ aStream nextPutAll: ' terminated)'. ^self ]. self isWaiting ifTrue: [ aStream nextPutAll: ' waiting on a semaphore)'. ^self ]. self isSuspended ifTrue: [ aStream nextPutAll: ' suspended)'. ^self ]. self isReady ifTrue: [ aStream nextPutAll: ' ready to run)'. ^self ]. aStream nextPutAll: ' undefined state)'. ! ! !Process methodsFor: 'accessing'! name ^name ! name: aString "Give the name aString to the process" name := aString ! priority "Answer the receiver's priority" ^priority ! priority: anInteger "Change the receiver's priority to anInteger" "If we are running, change the list" (anInteger < Processor lowestPriority) | (anInteger > Processor highestPriority) ifTrue: [ self error: 'invalid priority' ]. self isReady ifTrue: [ myList := Processor changePriorityOf: self to: anInteger ]. priority := anInteger ! queueInterrupt: aBlock "Force the receiver to be interrupted and to evaluate aBlock as soon as it becomes the active process (this could mean NOW if the receiver is active). Answer the receiver" self isActive ifTrue: [ aBlock value. ^self ]. self isTerminated ifTrue: [ self error: 'cannot interrupt terminated process' ]. suspendedContext := aBlock asContext: suspendedContext. ! ! !Process methodsFor: 'private'! exceptionHandlers exceptionHandlers isNil ifTrue: [ exceptionHandlers := Dictionary new ]. ^exceptionHandlers ! exceptionHandlers: handlers exceptionHandlers := handlers. ! onBlock: aBlock at: aPriority suspendedContext := aBlock. priority := aPriority. "By default we're suspended, so don't set myList!" ! isActive "Answer whether the receiver is running" ^self == Processor activeProcess ! isReady "Answer whether the receiver is not suspended nor waiting on a semaphore (maybe it is active, maybe it is not, though)" ^myList == (Processor processesAt: priority) ! isSuspended "Answer whether the receiver is suspended through #suspend" ^myList isNil ! isTerminated "Answer whether the receiver has already terminated" ^suspendedContext isNil ! isWaiting "Answer whether the receiver is wating on a semaphore" ^self isReady not & self isSuspended not ! !