--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ProcessMonitorV2.st Tue Jan 21 16:17:38 2003 +0100
@@ -0,0 +1,1787 @@
+"{ Package: 'stx:libtool' }"
+
+SystemStatusMonitorV2 subclass:#ProcessMonitorV2
+ instanceVariableNames:'processList tableColumns selectedProcesses updateSema showDetail
+ hasSelection selctionRestartable showProcessId showGroup
+ showState showPrio showUsedStack showTotalStack
+ showCurrentSegment showSwitch showWhere currentSortOrder
+ processTable processes showDead sortBlock selectionRestartable'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Monitors-ST/X'
+!
+
+Object subclass:#ProcessItem
+ instanceVariableNames:'processId processGroup processName processState processPrio
+ processUsedStack processTotalStack processWhere processInstance
+ processCurrentSegment processSwitch prioVal idVal groupVal'
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:ProcessMonitorV2
+!
+
+!ProcessMonitorV2 class methodsFor:'documentation'!
+
+documentation
+"
+ documentation to be added.
+
+ [author:]
+ Christian Penk (penk@bierfix)
+
+ [instance variables:]
+
+ [class variables:]
+
+ [see also:]
+
+"
+!
+
+examples
+"
+ Starting the application:
+ [exBegin]
+ ProcessMonitorV2 open
+
+ [exEnd]
+
+ more examples to be added:
+ [exBegin]
+ ... add code fragment for
+ ... executable example here ...
+ [exEnd]
+"
+!
+
+history
+ "Created: / 14.1.2003 / 11:16:10 / penk"
+! !
+
+!ProcessMonitorV2 class methodsFor:'defaults'!
+
+defaultIcon
+ |i|
+
+ i := Image fromFile:'ProcMon.xbm'.
+ i notNil ifTrue:[^ i].
+ ^ super defaultIcon
+
+ "Modified: 23.1.1997 / 02:52:31 / cg"
+!
+
+defaultLabel
+ ^ 'Process Monitor'
+! !
+
+!ProcessMonitorV2 class methodsFor:'help specs'!
+
+helpSpec
+ "This resource specification was automatically generated
+ by the UIHelpTool of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the UIHelpTool may not be able to read the specification."
+
+ "
+ UIHelpTool openOnClass:ProcessMonitorV2
+ "
+
+ <resource: #help>
+
+ ^ super helpSpec addPairsFrom:#(
+
+#toggleDetails
+''
+
+)
+! !
+
+!ProcessMonitorV2 class methodsFor:'image specs'!
+
+detailsMenuIconDown
+ "This resource specification was automatically generated
+ by the ImageEditor of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the ImageEditor may not be able to read the specification."
+
+ "
+ self detailsMenuIconDown inspect
+ ImageEditor openOnClass:self andSelector:#detailsMenuIconDown
+ Icon flushCachedIcons
+ "
+
+ <resource: #image>
+
+ ^Icon
+ constantNamed:#'ProcessMonitorV2 class detailsMenuIconDown'
+ ifAbsentPut:[(Depth1Image new) width: 7; height: 5; photometric:(#palette); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@b') ; colorMapFromArray:#[0 0 0 255 255 255]; mask:((Depth1Image new) width: 7; height: 5; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@A@(UJ(b') ; yourself); yourself]
+!
+
+detailsMenuIconUp
+ "This resource specification was automatically generated
+ by the ImageEditor of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the ImageEditor may not be able to read the specification."
+
+ "
+ self detailsMenuIconUp inspect
+ ImageEditor openOnClass:self andSelector:#detailsMenuIconUp
+ Icon flushCachedIcons
+ "
+
+ <resource: #image>
+
+ ^Icon
+ constantNamed:#'ProcessMonitorV2 class detailsMenuIconUp'
+ ifAbsentPut:[(Depth1Image new) width: 7; height: 5; photometric:(#palette); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@b') ; colorMapFromArray:#[0 0 0 255 255 255]; mask:((Depth1Image new) width: 7; height: 5; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'*%P(D@@b') ; yourself); yourself]
+!
+
+viewDetailsIcon
+ "This resource specification was automatically generated
+ by the ImageEditor of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the ImageEditor may not be able to read the specification."
+
+ "
+ self viewDetailsIcon inspect
+ ImageEditor openOnClass:self andSelector:#viewDetailsIcon
+ Icon flushCachedIcons
+ "
+
+ <resource: #image>
+
+ ^Icon
+ constantNamed:#'ProcessMonitorV2 class viewDetailsIcon'
+ ifAbsentPut:[(Depth1Image new) width: 16; height: 16; photometric:(#palette); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@b') ; colorMapFromArray:#[0 0 0 255 255 255]; mask:((Depth1Image new) width: 16; height: 16; photometric:(#blackIs0); bitsPerSample:(#(1 )); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@@@]+X@@@@@]+X@@@@@]+X@@@@@]+X@@@@@@@@b') ; yourself); yourself]
+! !
+
+!ProcessMonitorV2 class methodsFor:'interface specs'!
+
+windowSpec
+ "This resource specification was automatically generated
+ by the UIPainter of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the UIPainter may not be able to read the specification."
+
+ "
+ UIPainter new openOnClass:ProcessMonitorV2 andSelector:#windowSpec
+ ProcessMonitorV2 new openInterface:#windowSpec
+ ProcessMonitorV2 open
+ "
+
+ <resource: #canvas>
+
+ ^
+ #(#FullSpec
+ #name: #windowSpec
+ #window:
+ #(#WindowSpec
+ #label: 'ProcessMonitorV2'
+ #name: 'ProcessMonitorV2'
+ #min: #(#Point 10 10)
+ #max: #(#Point 1024 768)
+ #bounds: #(#Rectangle 16 42 781 379)
+ #menu: #mainMenu
+ )
+ #component:
+ #(#SpecCollection
+ #collection: #(
+ #(#MenuPanelSpec
+ #name: 'ToolBar1'
+ #layout: #(#LayoutFrame 0 0.0 0 0 0 1.0 32 0)
+ #menu: #toolBarMainMenu
+ #textDefault: true
+ )
+ #(#DataSetSpec
+ #name: 'Process Table'
+ #layout: #(#LayoutFrame 0 0.0 32 0.0 0 1.0 0 1.0)
+ #model: #selectedProcesses
+ #menu: #tableMenu
+ #hasHorizontalScrollBar: true
+ #hasVerticalScrollBar: true
+ #dataList: #processList
+ #useIndex: false
+ #has3Dsepartors: false
+ #doubleClickSelector: #doubleClickedAt:
+ #columnHolder: #tableColumns
+ #multipleSelectOk: true
+ #verticalSpacing: 0
+ #postBuildCallback: #postBuildProcessTable:
+ )
+ )
+
+ )
+ )
+! !
+
+!ProcessMonitorV2 class methodsFor:'menu specs'!
+
+mainMenu
+ "This resource specification was automatically generated
+ by the MenuEditor of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the MenuEditor may not be able to read the specification."
+
+ "
+ MenuEditor new openOnClass:ProcessMonitorV2 andSelector:#mainMenu
+ (Menu new fromLiteralArrayEncoding:(ProcessMonitorV2 mainMenu)) startUp
+ "
+
+ <resource: #menu>
+
+ ^
+ #(#Menu
+ #(
+ #(#MenuItem
+ #label: 'Exit'
+ #itemValue: #closeRequest
+ #translateLabel: true
+ )
+ #(#MenuItem
+ #label: 'Help'
+ #translateLabel: true
+ #startGroup: #right
+ #submenu:
+ #(#Menu
+ #(
+ #(#MenuItem
+ #label: 'Documentation'
+ #itemValue: #openDocumentation
+ #translateLabel: true
+ )
+ #(#MenuItem
+ #label: '-'
+ )
+ #(#MenuItem
+ #label: 'About this Application'
+ #itemValue: #openAboutThisApplication
+ #translateLabel: true
+ )
+ )
+ nil
+ nil
+ )
+ )
+ )
+ nil
+ nil
+ )
+!
+
+tableMenu
+ "This resource specification was automatically generated
+ by the MenuEditor of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the MenuEditor may not be able to read the specification."
+
+ "
+ MenuEditor new openOnClass:ProcessMonitorV2 andSelector:#tableMenu
+ (Menu new fromLiteralArrayEncoding:(ProcessMonitorV2 tableMenu)) startUp
+ "
+
+ <resource: #menu>
+
+ ^
+ #(#Menu
+ #(
+ #(#MenuItem
+ #enabled: #hasSelection
+ #label: 'Inspect'
+ #itemValue: #inspectSelection
+ #translateLabel: true
+ )
+ #(#MenuItem
+ #enabled: #hasSelection
+ #label: 'Debug'
+ #itemValue: #debugProcess
+ #translateLabel: true
+ )
+ #(#MenuItem
+ #label: '-'
+ )
+ #(#MenuItem
+ #enabled: #hasSelection
+ #label: 'Resume'
+ #itemValue: #resumeProcess
+ #translateLabel: true
+ )
+ #(#MenuItem
+ #enabled: #hasSelection
+ #label: 'Suspend'
+ #itemValue: #suspendProcess
+ #translateLabel: true
+ )
+ #(#MenuItem
+ #enabled: #hasSelection
+ #label: 'Stop'
+ #itemValue: #stopProcess
+ #translateLabel: true
+ )
+ #(#MenuItem
+ #label: '-'
+ )
+ #(#MenuItem
+ #enabled: #hasSelection
+ #label: 'Abort'
+ #itemValue: #abortProcess
+ #translateLabel: true
+ )
+ #(#MenuItem
+ #enabled: #hasSelection
+ #label: 'Terminate'
+ #itemValue: #terminateProcess
+ #translateLabel: true
+ )
+ #(#MenuItem
+ #enabled: #hasSelection
+ #label: 'Hard Terminate'
+ #itemValue: #hardTerminateProcess
+ #translateLabel: true
+ )
+ #(#MenuItem
+ #enabled: #hasSelection
+ #label: 'Terminate Group'
+ #itemValue: #terminateProcessGroup
+ #translateLabel: true
+ )
+ #(#MenuItem
+ #enabled: #selectionRestartable
+ #label: 'Restart'
+ #itemValue: #restartProcess
+ #translateLabel: true
+ )
+ #(#MenuItem
+ #label: '-'
+ )
+ #(#MenuItem
+ #enabled: #hasSelection
+ #label: 'Raise Prio'
+ #itemValue: #raisePrio
+ #translateLabel: true
+ )
+ #(#MenuItem
+ #enabled: #hasSelection
+ #label: 'Lower Prio'
+ #itemValue: #lowerPrio
+ #translateLabel: true
+ )
+ #(#MenuItem
+ #label: '-'
+ )
+ #(#MenuItem
+ #label: 'Update'
+ #itemValue: #updateView
+ #translateLabel: true
+ )
+ )
+ nil
+ nil
+ )
+!
+
+toolBarMainMenu
+ "This resource specification was automatically generated
+ by the MenuEditor of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the MenuEditor may not be able to read the specification."
+
+ "
+ MenuEditor new openOnClass:ProcessMonitorV2 andSelector:#toolBarMainMenu
+ (Menu new fromLiteralArrayEncoding:(ProcessMonitorV2 toolBarMainMenu)) startUp
+ "
+
+ <resource: #menu>
+
+ ^
+ #(#Menu
+ #(
+ #(#MenuItem
+ #enabled: #hasSelection
+ #label: 'Inspect'
+ #itemValue: #inspectSelection
+ #translateLabel: true
+ #isButton: true
+ #labelImage: #(#ResourceRetriever #SystemBrowser #watchIcon)
+ )
+ #(#MenuItem
+ #activeHelpKey: #toggleDetails
+ #label: 'View Details'
+ #translateLabel: true
+ #isButton: true
+ #startGroup: #right
+ #submenuChannel: #viewDetailsMenuSpec
+ #labelImage: #(#ResourceRetriever #ProcessMonitorV2 #viewDetailsIcon)
+ )
+ )
+ nil
+ nil
+ )
+!
+
+viewDetailsMenuSpec
+ "This resource specification was automatically generated
+ by the MenuEditor of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the MenuEditor may not be able to read the specification."
+
+ "
+ MenuEditor new openOnClass:ProcessMonitorV2 andSelector:#viewDetailsMenuSpec
+ (Menu new fromLiteralArrayEncoding:(ProcessMonitorV2 viewDetailsMenuSpec)) startUp
+ "
+
+ <resource: #menu>
+
+ ^
+ #(#Menu
+ #(
+ #(#MenuItem
+ #label: 'Id'
+ #translateLabel: true
+ #hideMenuOnActivated: false
+ #indication: #showProcessId
+ )
+ #(#MenuItem
+ #label: 'Group'
+ #translateLabel: true
+ #hideMenuOnActivated: false
+ #indication: #showGroup
+ )
+ #(#MenuItem
+ #label: 'State'
+ #translateLabel: true
+ #hideMenuOnActivated: false
+ #indication: #showState
+ )
+ #(#MenuItem
+ #label: 'Prio'
+ #translateLabel: true
+ #hideMenuOnActivated: false
+ #indication: #showPrio
+ )
+ #(#MenuItem
+ #label: 'Used Stack'
+ #translateLabel: true
+ #hideMenuOnActivated: false
+ #indication: #showUsedStack
+ )
+ #(#MenuItem
+ #label: 'Total Stack'
+ #translateLabel: true
+ #hideMenuOnActivated: false
+ #indication: #showTotalStack
+ )
+ #(#MenuItem
+ #label: 'Current-Segment'
+ #translateLabel: true
+ #hideMenuOnActivated: false
+ #indication: #showCurrentSegment
+ )
+ #(#MenuItem
+ #label: 'Switch'
+ #translateLabel: true
+ #hideMenuOnActivated: false
+ #indication: #showSwitch
+ )
+ #(#MenuItem
+ #label: 'Where'
+ #translateLabel: true
+ #hideMenuOnActivated: false
+ #indication: #showWhere
+ )
+ #(#MenuItem
+ #label: '-'
+ )
+ #(#MenuItem
+ #label: 'Show dead Processes'
+ #translateLabel: true
+ #indication: #showDead
+ )
+ )
+ nil
+ nil
+ )
+! !
+
+!ProcessMonitorV2 class methodsFor:'tableColumns specs'!
+
+tableColumns
+ "This resource specification was automatically generated
+ by the DataSetBuilder of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the DataSetBuilder may not be able to read the specification."
+
+ "
+ DataSetBuilder new openOnClass:ProcessMonitorV2 andSelector:#tableColumns
+ "
+
+ <resource: #tableColumns>
+
+ ^#(
+ #(#DataSetColumnSpec
+ #label: 'Id'
+ #id: #id
+ #labelAlignment: #left
+ #labelButtonType: #Button
+ #labelActionSelector: #sortProcessListBy:
+ #labelActionArgument: 'idVal'
+ #width: 45
+ #type: #number
+ #model: #processId
+ #canSelect: false
+ #showRowSeparator: false
+ #showColSeparator: false
+ )
+ #(#DataSetColumnSpec
+ #label: 'Group'
+ #id: #group
+ #labelAlignment: #left
+ #labelButtonType: #Button
+ #labelActionSelector: #sortProcessListBy:
+ #labelActionArgument: 'groupVal'
+ #width: 45
+ #model: #processGroup
+ #canSelect: false
+ #showRowSeparator: false
+ #showColSeparator: false
+ )
+ #(#DataSetColumnSpec
+ #label: 'Name'
+ #id: #name
+ #labelAlignment: #left
+ #labelButtonType: #Button
+ #labelActionSelector: #sortProcessListBy:
+ #labelActionArgument: 'processName'
+ #width: 200
+ #model: #processName
+ #canSelect: false
+ #showRowSeparator: false
+ #showColSeparator: false
+ )
+ #(#DataSetColumnSpec
+ #label: 'State'
+ #id: #state
+ #labelAlignment: #left
+ #labelButtonType: #Button
+ #labelActionSelector: #sortProcessListBy:
+ #labelActionArgument: 'processState'
+ #width: 100
+ #model: #processState
+ #canSelect: false
+ #showRowSeparator: false
+ #showColSeparator: false
+ )
+ #(#DataSetColumnSpec
+ #label: 'Prio'
+ #id: #prio
+ #labelAlignment: #left
+ #labelButtonType: #Button
+ #labelActionSelector: #sortProcessListBy:
+ #labelActionArgument: 'prioVal'
+ #width: 40
+ #model: #processPrio
+ #canSelect: false
+ #showRowSeparator: false
+ #showColSeparator: false
+ )
+ #(#DataSetColumnSpec
+ #label: 'Used Stack'
+ #id: #usedStack
+ #labelAlignment: #left
+ #labelButtonType: #Button
+ #labelActionSelector: #sortProcessListBy:
+ #labelActionArgument: 'processUsedStack'
+ #columnAlignment: #right
+ #width: 75
+ #type: #number
+ #model: #processUsedStack
+ #canSelect: false
+ #showRowSeparator: false
+ #showColSeparator: false
+ )
+ #(#DataSetColumnSpec
+ #label: 'Total Stack'
+ #id: #totalStack
+ #labelAlignment: #left
+ #labelButtonType: #Button
+ #labelActionSelector: #sortProcessListBy:
+ #labelActionArgument: 'processTotalStack'
+ #columnAlignment: #right
+ #width: 75
+ #model: #processTotalStack
+ #canSelect: false
+ #showRowSeparator: false
+ #showColSeparator: false
+ )
+ #(#DataSetColumnSpec
+ #label: 'Current-Segment'
+ #id: #currentSegment
+ #labelAlignment: #left
+ #labelButtonType: #Button
+ #labelActionSelector: #sortProcessListBy:
+ #labelActionArgument: 'processCurrentSegment'
+ #width: 110
+ #model: #processCurrentSegment
+ #canSelect: false
+ #showRowSeparator: false
+ #showColSeparator: false
+ )
+ #(#DataSetColumnSpec
+ #label: 'Switch'
+ #id: #switch
+ #labelAlignment: #left
+ #labelButtonType: #Button
+ #labelActionSelector: #sortProcessListBy:
+ #labelActionArgument: 'processSwitch'
+ #columnAlignment: #right
+ #width: 55
+ #type: #number
+ #model: #processSwitch
+ #canSelect: false
+ #showRowSeparator: false
+ #showColSeparator: false
+ )
+ #(#DataSetColumnSpec
+ #label: 'Where'
+ #id: #where
+ #labelAlignment: #left
+ #labelButtonType: #Button
+ #labelActionSelector: #sortProcessListBy:
+ #labelActionArgument: 'processWhere'
+ #model: #processWhere
+ #canSelect: false
+ #showRowSeparator: false
+ #showColSeparator: false
+ )
+ )
+
+! !
+
+!ProcessMonitorV2 methodsFor:'actions'!
+
+doubleClickedAt:anItemIndex
+ "open a debugger on the selected process"
+
+ self debugProcess
+!
+
+getProcessList
+ "select processes to display.
+ Subclasses may redefine this"
+
+ |coll|
+
+ self needFullInformation ifTrue:[
+ coll := Process allSubInstances asOrderedCollection.
+ ] ifFalse:[
+ coll := ProcessorScheduler knownProcesses asOrderedCollection.
+ ].
+ ^ coll
+!
+
+selectedProcessesDo:aBlock
+ | sel|
+
+ sel := self selectedProcesses value.
+ sel isNil ifTrue:[^ self].
+
+ sel do:[:processItem |
+ aBlock value:(processItem processInstance).
+ ]
+!
+
+selectedProcessesSend:aSelector
+ "send a message to all selected processes"
+
+ self selectedProcessesDo:[:p |
+ p perform:aSelector
+ ].
+ self updateView.
+! !
+
+!ProcessMonitorV2 methodsFor:'aspects'!
+
+currentSortOrder
+ "return/create the 'currentSortOrder' value holder (automatically generated)"
+
+ currentSortOrder isNil ifTrue:[
+ currentSortOrder := Dictionary new asValue.
+ ].
+ ^ currentSortOrder
+!
+
+hasSelection
+
+ hasSelection isNil ifTrue:[
+ hasSelection := ValueHolder new.
+ ].
+ ^ hasSelection
+!
+
+processList
+
+ processList isNil ifTrue:[
+ processList := List new.
+ ].
+ ^ processList.
+!
+
+selectedProcesses
+
+ selectedProcesses isNil ifTrue:[
+ selectedProcesses := ValueHolder new.
+ selectedProcesses addDependent:self.
+ ].
+ ^ selectedProcesses.
+!
+
+selectionRestartable
+
+ selectionRestartable isNil ifTrue:[
+ selectionRestartable := ValueHolder new.
+ ].
+ ^ selectionRestartable
+!
+
+showDead
+ "return/create the 'showDead' value holder (automatically generated)"
+
+ showDead isNil ifTrue:[
+ showDead := false asValue.
+ showDead addDependent:self.
+ ].
+ ^ showDead
+!
+
+sortBlock
+
+ sortBlock isNil ifTrue:[
+ sortBlock := [:a :b |
+ a idVal < b idVal
+ ]
+ ].
+ ^ sortBlock
+!
+
+tableColumns
+
+ tableColumns isNil ifTrue:[
+ tableColumns := self class tableColumns asValue.
+ ].
+ ^ tableColumns.
+! !
+
+!ProcessMonitorV2 methodsFor:'aspects column'!
+
+showCurrentSegment
+ "return/create the 'showCurrentSegment' value holder (automatically generated)"
+
+ showCurrentSegment isNil ifTrue:[
+ showCurrentSegment := showDetail asValue.
+ showCurrentSegment onChangeSend:#viewedColumnsChanged to:self.
+ ].
+ ^ showCurrentSegment
+!
+
+showGroup
+ "return/create the 'showGroup' value holder (automatically generated)"
+
+ showGroup isNil ifTrue:[
+ showGroup := true asValue.
+ showGroup onChangeSend:#viewedColumnsChanged to:self.
+ ].
+ ^ showGroup
+!
+
+showPrio
+ "return/create the 'showPrio' value holder (automatically generated)"
+
+ showPrio isNil ifTrue:[
+ showPrio := true asValue.
+ showPrio onChangeSend:#viewedColumnsChanged to:self.
+ ].
+ ^ showPrio
+!
+
+showProcessId
+
+ showProcessId isNil ifTrue:[
+ showProcessId := true asValue.
+ showProcessId onChangeSend:#viewedColumnsChanged to:self
+ ].
+ ^ showProcessId
+!
+
+showState
+ "return/create the 'showState' value holder (automatically generated)"
+
+ showState isNil ifTrue:[
+ showState := true asValue.
+ showState onChangeSend:#viewedColumnsChanged to:self
+ ].
+ ^ showState
+!
+
+showSwitch
+ "return/create the 'showSwitch' value holder (automatically generated)"
+
+ showSwitch isNil ifTrue:[
+ showSwitch := showDetail asValue.
+ showSwitch onChangeSend:#viewedColumnsChanged to:self
+ ].
+ ^ showSwitch
+!
+
+showTotalStack
+ "return/create the 'showTotalStack' value holder (automatically generated)"
+
+ showTotalStack isNil ifTrue:[
+ showTotalStack := showDetail asValue.
+ showTotalStack onChangeSend:#viewedColumnsChanged to:self
+ ].
+ ^ showTotalStack
+!
+
+showUsedStack
+ "return/create the 'showUsedStack' value holder (automatically generated)"
+
+ showUsedStack isNil ifTrue:[
+ showUsedStack := showDetail asValue.
+ showUsedStack onChangeSend:#viewedColumnsChanged to:self
+ ].
+ ^ showUsedStack
+!
+
+showWhere
+ "return/create the 'showWhere' value holder (automatically generated)"
+
+ showWhere isNil ifTrue:[
+ showWhere := true asValue.
+ showWhere onChangeSend:#viewedColumnsChanged to:self
+ ].
+ ^ showWhere
+! !
+
+!ProcessMonitorV2 methodsFor:'change & update'!
+
+selectionChanged
+
+ |allRestartable|
+
+ self hasSelection value:(self selectedProcesses value notEmptyOrNil).
+ self hasSelection value ifFalse:[
+ self selectionRestartable value:false.
+ ^ self
+ ].
+ allRestartable := true.
+ self selectedProcessesDo:[:p |
+ p isRestartable ifFalse:[
+ allRestartable := false
+ ].
+ ].
+ self selectionRestartable value:allRestartable.
+ ^ self.
+!
+
+update:something with:aParameter from:changedObject
+ "Invoked when an object that I depend upon sends a change notification."
+
+ "stub code automatically generated - please change as required"
+
+ changedObject == self selectedProcesses ifTrue:[
+ self selectionChanged.
+ ^ self
+ ].
+ changedObject == self showDead ifTrue:[
+ self updateStatus:nil.
+ ^ self
+ ].
+ super update:something with:aParameter from:changedObject
+!
+
+viewedColumnsChanged
+
+ | columns buffer locCurrentSortOrder currentSortOrderColumn currentSortOrderReverse selection|
+
+ selection := self selectedProcesses value.
+ columns := OrderedCollection new.
+ self class tableColumns do:[:el|
+ columns add:(DataSetColumnSpec new fromLiteralArrayEncoding:el).
+ ].
+ buffer := columns copy.
+ locCurrentSortOrder := self currentSortOrder value.
+ currentSortOrderColumn := locCurrentSortOrder at:#column ifAbsent:nil.
+ currentSortOrderReverse := locCurrentSortOrder at:#reverse ifAbsent:nil.
+ buffer do:[:col |
+ | id |
+ id := col id.
+ id notNil ifTrue:[
+ (col labelActionArgument notNil and:[col labelActionArgument asSymbol == currentSortOrderColumn]) ifTrue:[
+ | label icon|
+ label := col label.
+ icon := currentSortOrderReverse ifTrue:[self class detailsMenuIconDown] ifFalse:[self class detailsMenuIconUp].
+ col label:(LabelAndIcon label:label icon:icon).
+ ].
+ (id == #id and:[self showProcessId value not]) ifTrue:[
+ columns remove:col.
+ ] ifFalse:[
+ (id == #group and:[self showGroup value not]) ifTrue:[
+ columns remove:col.
+ ] ifFalse:[
+ (id == #prio and:[self showPrio value not]) ifTrue:[
+ columns remove:col.
+ ] ifFalse:[
+ (id == #currentSegment and:[self showCurrentSegment value not]) ifTrue:[
+ columns remove:col.
+ ] ifFalse:[
+ (id == #state and:[self showState value not]) ifTrue:[
+ columns remove:col.
+ ] ifFalse:[
+ (id == #switch and:[self showSwitch value not]) ifTrue:[
+ columns remove:col.
+ ] ifFalse:[
+ (id == #totalStack and:[self showTotalStack value not]) ifTrue:[
+ columns remove:col.
+ ] ifFalse:[
+ (id == #usedStack and:[self showUsedStack value not]) ifTrue:[
+ columns remove:col.
+ ] ifFalse:[
+ (id == #where and:[self showWhere value not]) ifTrue:[
+ columns remove:col.
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ].
+ updateSema critical:[
+ self tableColumns value:columns.
+ self selectedProcesses value:selection.
+ ].
+ self updateList.
+! !
+
+!ProcessMonitorV2 methodsFor:'event handling'!
+
+processEvent:anEvent
+ "filter keyboard events.
+ Return true, if I have eaten the event"
+
+ |focusView key rawKey|
+
+ anEvent isKeyPressEvent ifTrue:[
+ focusView := anEvent targetView.
+ key := anEvent key.
+ rawKey := anEvent rawKey.
+
+ (focusView == processList) ifTrue:[
+ key == #InspectIt ifTrue:[
+ self inspectSelection.
+ ^ true.
+ ].
+ ]
+ ].
+ ^ false
+! !
+
+!ProcessMonitorV2 methodsFor:'initialization & release'!
+
+closeDownViews
+ "This is a hook method generated by the Browser.
+ It will be invoked when your app/dialog-window is really closed.
+ See also #closeDownViews, which is invoked before and may suppress the close
+ or ask the user for confirmation."
+
+ "/ change the code below as required ...
+ "/ This should cleanup any leftover resources
+ "/ (for example, temporary files)
+ "/ super closeRequest will initiate the closeDown
+
+ "/ add your code here
+
+ "/ do not remove the one below ...
+ ^ super closeDownViews
+!
+
+initialize
+
+ super initialize.
+
+ showDetail := (Smalltalk at:#SystemDebugging ifAbsent:false).
+ updateSema := Semaphore forMutualExclusion.
+ updateDelay := 0.5.
+ listUpdateDelay := 5.
+
+ "/ event mode is no longer used;
+ "/ this event support may vanish
+ Processor isPureEventDriven ifTrue:[
+ updateBlock := [self updateStatus:nil].
+ listUpdateBlock := [self updateList].
+ ].
+!
+
+postBuildProcessTable:aWidget
+
+ processTable := aWidget scrolledView.
+ processTable wantsFocusWithPointerEnter.
+!
+
+postBuildWith:aBuilder
+
+ ^ super postBuildWith:aBuilder
+!
+
+postOpenWith:aBuilder
+
+ super postOpenWith:aBuilder.
+ self viewedColumnsChanged.
+ self updateList.
+ self startUpdateProcess.
+ self selectionChanged.
+ self windowGroup addPreEventHook:self.
+! !
+
+!ProcessMonitorV2 methodsFor:'menu actions'!
+
+abortProcess
+ "abort (raise AbortSignal in) the selected process"
+
+ self selectedProcessesDo:[:p |
+ p abort
+ ]
+!
+
+debugProcess
+ "open a debugger on the selected process"
+
+ self selectedProcessesDo:[:p |
+ Debugger openOn:p
+ ]
+!
+
+debugWhenResumed
+ self selectedProcessesDo:[:p |
+ p addInterruptAction:[Debugger enter]
+ ]
+!
+
+hardTerminateProcess
+ "hard terminate the selected process"
+
+ self selectedProcessesSend:#terminateNoSignal
+!
+
+inspectSelection
+ "open an inspector on the selected process"
+
+ self selectedProcessesSend:#inspect
+!
+
+lowerPrio
+ "lower the selected processes priority"
+
+ self selectedProcessesDo:[:p |
+ p priority:(p priority - 1)
+ ]
+!
+
+openAboutThisApplication
+ "This method was generated by the Browser.
+ It will be invoked when the menu-item 'help-about' is selected."
+
+ "/ could open a customized aboutBox here ...
+ super openAboutThisApplication
+!
+
+openDocumentation
+ "This method was generated by the Browser.
+ It will be invoked when the menu-item 'help-documentation' is selected."
+
+ "/ change below as required ...
+
+ "/ to open an HTML viewer on some document (under 'doc/online/<language>/' ):
+ HTMLDocumentView openFullOnDocumentationFile:'TOP.html'.
+
+ "/ add application-specific help files under the 'doc/online/<language>/help/appName'
+ "/ directory, and open a viewer with:
+ "/ HTMLDocumentView openFullOnDocumentationFile:'help/<MyApplication>/TOP.html'.
+!
+
+raisePrio
+ "raise the selected processes priority"
+
+ self selectedProcessesDo:[:p |
+ p priority:(p priority + 1)
+ ]
+!
+
+restartProcess
+ "abort (raise AbortSignal in) the selected process"
+
+ self selectedProcessesDo:[:p |
+ p restart.
+ ]
+!
+
+resumeProcess
+ "resume the selected process (i.e. let it run) "
+
+ self selectedProcessesSend:#resume
+!
+
+stopProcess
+ "stop the selected process - not even interrupts will wake it up"
+
+ self selectedProcessesSend:#stop
+!
+
+suspendProcess
+ "suspend the selected process - interrupts will let it run again"
+
+ self selectedProcessesSend:#suspend
+!
+
+terminateProcess
+ "terminate the selected process"
+
+ self selectedProcessesSend:#terminate.
+ self updateList.
+!
+
+terminateProcessGroup
+ "terminate the selected process with all of its subprocesses"
+
+ self selectedProcessesSend:#terminateGroup.
+ self updateList.
+! !
+
+!ProcessMonitorV2 methodsFor:'queries'!
+
+needFullInformation
+
+ ^ true
+"/ ^ (self showUsedStack value or:[
+"/ self showTotalStack value or:[
+"/ self showCurrentSegment value or:[
+"/ self showSwitch value]]])
+!
+
+showDetail
+! !
+
+!ProcessMonitorV2 methodsFor:'queries - table string'!
+
+getCurrentSegmentStringFor:con
+
+ con notNil ifTrue:[
+ | contextCount c sender|
+ contextCount := 1.
+ c := con.
+ [(sender := c sender) notNil] whileTrue:[
+ c := sender.
+ contextCount := contextCount + 1.
+ ].
+ ^ (((ObjectMemory addressOf:con) printStringRadix:16),
+ ' .. ',
+ ((ObjectMemory addressOf:c) printStringRadix:16)).
+ ].
+!
+
+getGroupStringFor:aProcess
+
+ |gId|
+
+ gId := aProcess processGroupId.
+ ((gId == aProcess id) or:[gId isNil]) ifTrue:[
+ "/ a group leader
+ ^ '-'.
+ ] ifFalse:[
+ ^ gId.
+ ].
+!
+
+getPrioStringFor:aProcess
+
+ |prioRange|
+
+ Processor supportDynamicPriorities ifTrue:[
+ (prioRange := aProcess priorityRange) isNil ifTrue:[
+ ^ aProcess priority asString.
+ ] ifFalse:[
+ ^ (aProcess priority asString,
+ ' [',
+ prioRange start printString,
+ '..',
+ prioRange stop printString,
+ ']').
+ ].
+ ].
+!
+
+getStateStringFor:aProcess running:isRunning
+
+ |st stateCharacter |
+
+ st := aProcess state.
+ isRunning ifTrue:[
+ stateCharacter := '* '.
+ ] ifFalse:[
+ [
+ (Processor scheduledProcesses includes:aProcess) ifTrue:[
+ stateCharacter := '+ '
+ ] ifFalse:[
+ stateCharacter := ' '.
+ ].
+ ] valueUninterruptably.
+ ].
+ ^ stateCharacter, (st asString).
+!
+
+getTotalStackStringFor:aProcess
+
+
+ aProcess id == 0 ifTrue:[
+ ^ 'unlimited'.
+ ] ifFalse:[
+ | tStackSize noOfSegs |
+ ((tStackSize := aProcess totalStackSize) notNil and:[
+ (noOfSegs := aProcess numberOfStackSegments) notNil
+ ]) ifTrue:[
+ ^ ((tStackSize printString),
+ ' (',
+ (noOfSegs printString),
+ ')' )
+ ]
+ ].
+!
+
+getWhereStringFor:con running:isRunning
+
+ con notNil ifTrue:[
+ | c found skipping|
+ c := con.
+ found := false.
+ isRunning ifFalse:[
+ "/ search for a semaphore-wait in the top 10 contexts
+
+ 1 to:10 do:[:n |
+ found ifFalse:[
+ c notNil ifTrue:[
+ (c receiver class == Semaphore) ifTrue:[
+ c selector == #wait ifTrue:[
+ found := true.
+ ]
+ ].
+ c := c sender.
+ ]
+ ]
+ ].
+ ].
+ found ifFalse:[
+ "/ search for a non-processor, non-process
+ "/ receiver in the top 10 contexts
+
+ c := con.
+ 1 to:10 do:[:n |
+ |r|
+
+ found ifFalse:[
+ c notNil ifTrue:[
+ ((r := c receiver) ~~ Processor
+ and:[r class ~~ Process]) ifTrue:[
+ found := true.
+ ] ifFalse:[
+ c := c sender.
+ ]
+ ]
+ ]
+ ]
+ ].
+ found ifFalse:[
+ c := con
+ ].
+
+ "/ skip, until an interesting context is
+ "/ found.
+ "/ this skips intermediate contexts, which lead
+ "/ to the sema-wait (for example, unwind blocks,
+ "/ delay-stuff etc.)
+
+ skipping := true.
+ [skipping] whileTrue:[
+ skipping := false.
+ (c notNil
+ and:[c receiver == Delay
+ or:[c receiver class == Delay]]) ifTrue:[
+ c := c sender.
+ skipping := true.
+ ].
+
+ [c notNil
+ and:[c receiver isBlock
+ and:[c selector startsWith:'value']]] whileTrue:[
+ c := c sender.
+ skipping := true.
+ ].
+
+ [c notNil
+ and:[c receiver isBlock
+ and:[c selector = 'ensure:']]] whileTrue:[
+ c := c sender.
+ skipping := true.
+ ].
+
+ [c notNil
+ and:[c receiver == OperatingSystem
+ and:[c selector == #unblockInterrupts]]] whileTrue:[
+ c := c sender.
+ skipping := true.
+ ].
+
+ [c notNil and:[c isBlockContext]] whileTrue:[
+ c := c home.
+ skipping := true.
+ ].
+ ].
+
+ c notNil ifTrue:[
+ | sel |
+ sel := c selector.
+ sel isNil ifTrue:[
+ sel := '* unknown *'
+ ].
+ ^ (c receiver class name,
+ '>>',
+ sel).
+ ]
+ ].
+! !
+
+!ProcessMonitorV2 methodsFor:'sorting'!
+
+sortProcessListBy:instanceName
+ "method to sort the list of BugReport"
+
+ | aSymbol isReverse cmpOp currentSortOrder|
+
+ aSymbol := instanceName asSymbol.
+ isReverse := false.
+ currentSortOrder := self currentSortOrder value.
+ currentSortOrder isEmpty ifTrue:[
+ currentSortOrder at:#column put:aSymbol.
+ currentSortOrder at:#reverse put:false.
+ ] ifFalse:[
+ (currentSortOrder at:#column) = aSymbol ifTrue:[
+ "/ same column like before - change sort order ifReverse is true
+ isReverse := currentSortOrder at:#reverse.
+ currentSortOrder at:#reverse put:(isReverse not).
+ ] ifFalse:[
+ "/ another column - remark column
+ currentSortOrder at:#column put:aSymbol.
+ ]
+ ].
+ self viewedColumnsChanged.
+ (currentSortOrder at:#reverse) ifTrue:[
+ cmpOp := #'>'
+ ] ifFalse:[
+ cmpOp := #'<'
+ ].
+ sortBlock := [:a :b |
+ |entry1 entry2|
+
+ entry1 := (a perform:aSymbol).
+ entry2 := (b perform:aSymbol).
+ entry1 perform:cmpOp with:entry2
+ ].
+ updateSema critical:[
+ | oldList |
+ oldList := self processList copy.
+ self processList contents:(oldList sort:sortBlock)
+ ].
+! !
+
+!ProcessMonitorV2 methodsFor:'update process'!
+
+createItemWith:aProcess
+
+ | running con processItem|
+
+ processItem := ProcessItem new.
+
+ processItem processInstance:aProcess.
+
+ processItem processId:aProcess id.
+ processItem idVal:aProcess id ? -1.
+
+ processItem processGroup:(self getGroupStringFor:aProcess).
+ processItem groupVal:(processItem processGroup isNumber ifTrue:[processItem processGroup] ifFalse:[-1]).
+
+ processItem processName:aProcess name ? ''.
+
+ running := (aProcess state == #run and:[aProcess == Processor interruptedProcess]).
+
+ processItem processState:(self getStateStringFor:aProcess running:running).
+
+ processItem prioVal:(aProcess priority).
+ processItem processPrio:(self getPrioStringFor:aProcess).
+
+ processItem processUsedStack:aProcess usedStackSize.
+
+ processItem processTotalStack:(self getTotalStackStringFor:aProcess).
+
+ con := aProcess suspendedContext.
+ con isNil ifTrue:[
+ aProcess == Processor activeProcess ifTrue:[
+ con := thisContext
+ ]
+ ].
+
+ processItem processCurrentSegment:(self getCurrentSegmentStringFor:con).
+
+ processItem processSwitch:(aProcess numberOfStackBoundaryHits printString).
+
+ processItem processWhere:(self getWhereStringFor:con running:running).
+
+ ^ processItem
+!
+
+startUpdateProcess
+ updateBlock notNil ifTrue:[
+ Processor addTimedBlock:updateBlock afterSeconds:updateDelay.
+ Processor addTimedBlock:listUpdateBlock afterSeconds:listUpdateDelay.
+ ] ifFalse:[
+ updateProcess := [
+ [
+ |id cnt myDelay|
+
+ myDelay := Delay forSeconds:updateDelay.
+
+ "
+ every updateDelay (0.5), we look which process runs;
+ every half second, the status is updated.
+ every listUpdateDelay (5s), the list of processes is
+ built up again
+ "
+ [true] whileTrue:[
+ ((listUpdateDelay // updateDelay) max:2) - 1 timesRepeat:[
+ myDelay wait.
+ self updateStatus:nil.
+ ].
+ myDelay wait.
+ self updateList.
+ ]
+ ] valueOnUnwindDo:[
+ updateProcess := nil
+ ]
+ ] forkAt:(Processor userSchedulingPriority + 1).
+ updateProcess name:'monitor [' ,
+ Processor activeProcess id printString ,
+ '] update'.
+ "
+ raise my own priority
+ "
+ Processor activeProcess priority:(Processor userSchedulingPriority + 2)
+ ].
+!
+
+updateList
+
+ |newList|
+
+ processTable shown ifTrue:[
+ newList := self getProcessList.
+
+ "sort by id - take care of nil ids of dead processes"
+ newList sort:[:p1 :p2 |
+ |id1 id2|
+
+ (p1 isNil or:[(id1 := p1 id) isNil])
+ ifTrue:[true]
+ ifFalse:[
+ (p2 isNil or:[(id2 := p2 id) isNil])
+ ifTrue:[false]
+ ifFalse:[id1 < id2]
+ ]
+ ].
+ newList ~= processes ifTrue:[
+ self updateStatus:newList
+ ].
+ ].
+ updateBlock notNil ifTrue:[
+ Processor removeTimedBlock:listUpdateBlock.
+ Processor addTimedBlock:listUpdateBlock afterSeconds:listUpdateDelay
+ ].
+!
+
+updateStatus:newProcessList
+
+ |startTime oldSelection newSelection newList dIndex index aProcess processItem endTime deltaT|
+
+ startTime := AbsoluteTime now.
+
+ processTable shown ifTrue:[
+ newProcessList notNil ifTrue:[
+ processes := WeakArray withAll:newProcessList.
+ ((processes findFirst:[:pro1| pro1 id == 0]) ~= 0) ifTrue:[
+ Transcript showCR:'have'.
+ ].
+ ].
+ processes notNil ifTrue:[
+ newList := OrderedCollection new.
+
+ dIndex := 1.
+ index := 1.
+
+ "/ use while-loop;
+ "/ processList may change size ....
+
+ [index <= processes size] whileTrue:[
+ aProcess := processes at:index.
+ index := index + 1.
+ (aProcess notNil
+ and:[aProcess ~~ 0]) ifTrue:[
+ ((aProcess id) notNil or:[self showDead value]) ifTrue:[
+ processItem := self createItemWith:aProcess.
+ (((newList select:[:pro2| (pro2 processInstance == processItem processInstance)]) size) > 0) ifTrue:[
+ Transcript showCR:'process ', processItem processInstance name asString, ' already in list at ', index asString.
+ ].
+ newList add:processItem.
+ processes at:dIndex put:aProcess.
+ ]
+ ].
+ dIndex := dIndex + 1
+ ]
+ ].
+ updateSema critical:[
+ oldSelection := self selectedProcesses value.
+ newList sort:self sortBlock.
+ processList contents:(newList asList).
+ oldSelection notNil ifTrue:[
+ newSelection := OrderedCollection new.
+ oldSelection do:[:processItem |
+ index := newList findFirst:[:anItem | (anItem processInstance == processItem processInstance)].
+ index ~~ 0 ifTrue:[
+ newSelection add:(newList at:index).
+ ].
+ ]
+ ].
+ self selectedProcesses value:newSelection.
+ ]
+ ].
+ endTime := AbsoluteTime now.
+ deltaT := (endTime millisecondDeltaFrom:startTime) / 1000.0.
+"/ Transcript show:deltaT; show:' ' ; showCR:(updateDelay / 10.0).
+ deltaT > (updateDelay / 5) ifTrue:[
+ "/ the update took longer than 20% - make delay longer, to reduce cpu load.
+ updateDelay := updateDelay * 2.
+ "/ Transcript show:'+++ '; showCR:updateDelay.
+ ] ifFalse:[
+ updateDelay > 0.5 ifTrue:[
+ deltaT < (updateDelay / 20) ifTrue:[
+ "/ the update took less than 5% - make delay smaller for better animation.
+ updateDelay := (updateDelay / 2) max:0.5.
+ "/ Transcript show:'--- ';showCR:updateDelay.
+ ].
+ ].
+ ].
+
+ updateBlock notNil ifTrue:[
+ Processor removeTimedBlock:updateBlock.
+ Processor addTimedBlock:updateBlock afterSeconds:updateDelay
+ ]
+!
+
+updateView
+ self updateList.
+ self updateStatus:nil
+! !
+
+!ProcessMonitorV2::ProcessItem methodsFor:'accessing'!
+
+groupVal
+ "return the value of the instance variable 'groupVal' (automatically generated)"
+
+ ^ groupVal
+!
+
+groupVal:something
+ "set the value of the instance variable 'groupVal' (automatically generated)"
+
+ groupVal := something.
+!
+
+idVal
+ "return the value of the instance variable 'idVal' (automatically generated)"
+
+ ^ idVal
+!
+
+idVal:something
+ "set the value of the instance variable 'idVal' (automatically generated)"
+
+ idVal := something.
+!
+
+prioVal
+ "return the value of the instance variable 'prioVal' (automatically generated)"
+
+ ^ prioVal
+!
+
+prioVal:something
+ "set the value of the instance variable 'prioVal' (automatically generated)"
+
+ prioVal := something.
+!
+
+processCurrentSegment
+ "return the value of the instance variable 'processCurrentSegment' (automatically generated)"
+
+ ^ processCurrentSegment
+!
+
+processCurrentSegment:something
+ "set the value of the instance variable 'processCurrentSegment' (automatically generated)"
+
+ processCurrentSegment := something.
+!
+
+processGroup
+ "return the value of the instance variable 'processGroup' (automatically generated)"
+
+ ^ processGroup
+!
+
+processGroup:something
+ "set the value of the instance variable 'processGroup' (automatically generated)"
+
+ processGroup := something.
+!
+
+processId
+ "return the value of the instance variable 'processId' (automatically generated)"
+
+ ^ processId
+!
+
+processId:something
+ "set the value of the instance variable 'processId' (automatically generated)"
+
+ processId := something.
+!
+
+processInstance
+ "return the value of the instance variable 'processInstance' (automatically generated)"
+
+ ^ processInstance
+!
+
+processInstance:something
+ "set the value of the instance variable 'processInstance' (automatically generated)"
+
+ processInstance := something.
+!
+
+processName
+ "return the value of the instance variable 'processName' (automatically generated)"
+
+ ^ processName
+!
+
+processName:something
+ "set the value of the instance variable 'processName' (automatically generated)"
+
+ processName := something.
+!
+
+processPrio
+ "return the value of the instance variable 'processPrio' (automatically generated)"
+
+ ^ processPrio
+!
+
+processPrio:something
+ "set the value of the instance variable 'processPrio' (automatically generated)"
+
+ processPrio := something.
+!
+
+processState
+ "return the value of the instance variable 'processState' (automatically generated)"
+
+ ^ processState
+!
+
+processState:something
+ "set the value of the instance variable 'processState' (automatically generated)"
+
+ processState := something.
+!
+
+processSwitch
+ "return the value of the instance variable 'processSwitch' (automatically generated)"
+
+ ^ processSwitch
+!
+
+processSwitch:something
+ "set the value of the instance variable 'processSwitch' (automatically generated)"
+
+ processSwitch := something.
+!
+
+processTotalStack
+ "return the value of the instance variable 'processTotalStack' (automatically generated)"
+
+ ^ processTotalStack
+!
+
+processTotalStack:something
+ "set the value of the instance variable 'processTotalStack' (automatically generated)"
+
+ processTotalStack := something.
+!
+
+processUsedStack
+ "return the value of the instance variable 'processUsedStack' (automatically generated)"
+
+ ^ processUsedStack
+!
+
+processUsedStack:something
+ "set the value of the instance variable 'processUsedStack' (automatically generated)"
+
+ processUsedStack := something.
+!
+
+processWhere
+ "return the value of the instance variable 'processWhere' (automatically generated)"
+
+ ^ processWhere
+!
+
+processWhere:something
+ "set the value of the instance variable 'processWhere' (automatically generated)"
+
+ processWhere := something.
+! !
+
+!ProcessMonitorV2 class methodsFor:'documentation'!
+
+version
+ ^ '$Header: /cvs/stx/stx/libtool/ProcessMonitorV2.st,v 1.1 2003-01-21 15:17:24 penk Exp $'
+! !
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SystemStatusMonitorV2.st Tue Jan 21 16:17:38 2003 +0100
@@ -0,0 +1,34 @@
+"{ Package: 'stx:libtool' }"
+
+ApplicationModel subclass:#SystemStatusMonitorV2
+ instanceVariableNames:'listUpdateDelay updateDelay updateBlock listUpdateBlock
+ updateProcess'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'Monitors-ST/X'
+!
+
+
+!SystemStatusMonitorV2 methodsFor:'initialization & release'!
+
+release
+ updateBlock notNil ifTrue:[
+ Processor removeTimedBlock:updateBlock.
+ updateBlock := nil.
+ ].
+ listUpdateBlock notNil ifTrue:[
+ Processor removeTimedBlock:listUpdateBlock.
+ listUpdateBlock := nil.
+ ].
+ updateProcess notNil ifTrue:[
+ updateProcess terminate.
+ updateProcess := nil.
+ ].
+ super release
+! !
+
+!SystemStatusMonitorV2 class methodsFor:'documentation'!
+
+version
+ ^ '$Header: /cvs/stx/stx/libtool/Attic/SystemStatusMonitorV2.st,v 1.1 2003-01-21 15:17:38 penk Exp $'
+! !