tim Rowledge uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-tpr.798.mcz
==================== Summary ====================
Name: Tools-tpr.798
Author: tpr
Time: 7 March 2018, 11:19:49.739206 am
UUID: cf6625fc-e8fc-491a-8ec9-1d907f10e710
Ancestors: Tools-mt.797
Convert usage of nasty old StandardFileMenu to gleaming new file dialogues
=============== Diff against Tools-mt.797 ===============
Item was changed:
----- Method: ArchiveViewer>>extractMember (in category 'member operations') -----
extractMember
"Extract the member after prompting for a filename.
Answer the filename, or nil if error."
+ | name |
- | result name |
self canExtractMember ifFalse: [ ^nil ].
+ name := FileSaverDialog openOn: FileDirectory default.
+ name ifNil: [ ^nil ].
- result := StandardFileMenu newFile.
- result ifNil: [ ^nil ].
- name := (result directory fullNameFor: result name).
(archive canWriteToFileNamed: name)
ifFalse: [ self inform: name, ' is used by one or more members
in your archive, and cannot be overwritten.
Try extracting to another file name'.
^nil ].
self selectedMember extractToFileNamed: name.
^name!
Item was changed:
----- Method: ArchiveViewer>>writePrependingFile (in category 'archive operations') -----
writePrependingFile
| result name prependedName |
self canSaveArchive ifFalse: [ ^self ].
+ name := FileSaverDialog openOn: FileDirectory default initialFilename: 'archive.zip' label: 'Choose location to save archive' translated.
+ name ifNil: [ ^self ].
- result := (StandardFileMenu newFileMenu: FileDirectory default)
- startUpWithCaption: 'Destination Zip File Name:' translated.
- result ifNil: [ ^self ].
- name := result directory fullNameFor: result name.
(archive canWriteToFileNamed: name)
ifFalse: [ self inform: name, ' is used by one or more members
in your archive, and cannot be overwritten.
Try writing to another file name' translated.
^self ].
+ result := FileSaverDialog openOn: FileDirectory default initialFilename: 'archive.zip' label: 'Prepended File:' translated.
- result := (StandardFileMenu oldFileMenu: FileDirectory default)
- startUpWithCaption: 'Prepended File:' translated.
result ifNil: [ ^self ].
prependedName := result directory fullNameFor: result name.
[ archive writeToFileNamed: name prependingFileNamed: prependedName ]
on: Error
do: [ :ex | self inform: ex description. ].
self changed: #memberList "in case CRC's and compressed sizes got set"!
Item was changed:
----- Method: ChangeSorter>>fileIntoNewChangeSet (in category 'changeSet menu') -----
fileIntoNewChangeSet
"Obtain a file designation from the user, and file its contents into a
new change set whose name is a function of the filename. Show the
new set and leave the current changeSet unaltered."
+ | aNewChangeSet stream fileName |
- | aNewChangeSet stream |
self okToChange
ifFalse: [^ self].
ChangeSet promptForDefaultChangeSetDirectoryIfNecessary.
+ fileName := (FileChooserDialog openOn: ChangeSet defaultChangeSetDirectory) ifNil: [^nil].
+ stream := FileStream oldFileNamed: fileName.
+ stream ifNil: [^ self].
+
- stream := StandardFileMenu oldFileStreamFrom: ChangeSet defaultChangeSetDirectory.
- stream
- ifNil: [^ self].
aNewChangeSet := self class
newChangesFromStream: stream
+ named: (FileDirectory localNameFor:fileName).
- named: (FileDirectory localNameFor: stream name).
aNewChangeSet
ifNotNil: [self showChangeSet: aNewChangeSet]!
Item was changed:
----- Method: FileList class>>openFileDirectly (in category 'instance creation') -----
openFileDirectly
+ | fileName |
+ (fileName :=FileChooserDialog openOn: FileDirectory default) ifNotNil:
+ [self openEditorOn: (FileStream readOnlyFileNamed: fileName) editString: nil]!
- | aResult |
- (aResult := StandardFileMenu oldFile) ifNotNil:
- [self openEditorOn: (aResult directory readOnlyFileNamed: aResult name) editString: nil]!
Levente Uzonyi uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ul.1157.mcz
==================== Summary ====================
Name: Kernel-ul.1157
Author: ul
Time: 5 March 2018, 8:52:06.571627 pm
UUID: d0cb2a27-7e25-44de-9a35-1c498e2083d1
Ancestors: Kernel-ul.1156
Monitor changes:
- Monitor is now a subclass of Mutex.
- All methods implemented by Mutex have been removed from Monitor.
- The ownerProcess instance variable has been removed, because Mutex has its own owner instance variable. It was not referenced from Monitor's code.
- queuesMutex is now a Mutex instead of a Semaphore.
- Removed the unused mutex variable.
=============== Diff against Kernel-ul.1156 ===============
Item was changed:
+ Mutex subclass: #Monitor
+ instanceVariableNames: 'defaultQueue queueDict queuesMutex nestingLevel'
- LinkedList subclass: #Monitor
- instanceVariableNames: 'ownerProcess defaultQueue queueDict queuesMutex mutex nestingLevel'
classVariableNames: ''
poolDictionaries: ''
category: 'Kernel-Processes'!
!Monitor commentStamp: 'eem 1/7/2016 11:38' prior: 0!
A monitor provides process synchronization that is more high level than the one provided by a Semaphore. Similar to the classical definition of a Monitor it has the following properties:
1) At any time, only one process can execute code inside a critical section of a monitor.
2) A monitor is reentrant, which means that the active process in a monitor never gets blocked when it enters a (nested) critical section of the same monitor. For example a monitor will not block when trying the following:
| m |
m := Monitor new.
m critical: [m critical: [#yes]]
whereas a Semaphore will deadlock:
| s |
s := Semaphore forMutualExclusion.
s critical: [s critical: [#no]]
3) Inside a critical section, a process can wait for an event that may be coupled to a certain condition. If the condition is not fulfilled, the process leaves the monitor temporarily (in order to let other processes enter) and waits until another process signals the event. Then, the original process checks the condition again (this is often necessary because the state of the monitor could have changed in the meantime) and continues if it is fulfilled.
4) The monitor is fair, which means that the process that is waiting on a signaled condition the longest gets activated first.
5) The monitor allows you to define timeouts after which a process gets activated automatically.
Basic usage:
Monitor>>critical: aBlock
Critical section.
Executes aBlock as a critical section. At any time, only one process can execute code in a critical section.
NOTE: All the following synchronization operations are only valid inside the critical section of the monitor!!
Monitor>>wait
Unconditional waiting for the default event.
The current process gets blocked and leaves the monitor, which means that the monitor allows another process to execute critical code. When the default event is signaled, the original process is resumed.
Monitor>>waitWhile: aBlock
Conditional waiting for the default event.
The current process gets blocked and leaves the monitor only if the argument block evaluates to true. This means that another process can enter the monitor. When the default event is signaled, the original process is resumed, which means that the condition (argument block) is checked again. Only if it evaluates to false, does execution proceed. Otherwise, the process gets blocked and leaves the monitor again...
Monitor>>waitUntil: aBlock
Conditional waiting for the default event.
See Monitor>>waitWhile: aBlock.
Monitor>>signal
One process waiting for the default event is woken up.
Monitor>>signalAll
All processes waiting for the default event are woken up.
Using non-default (specific) events:
Monitor>>waitFor: aSymbol
Unconditional waiting for the non-default event represented by the argument symbol.
Same as Monitor>>wait, but the process gets only reactivated by the specific event and not the default event.
Monitor>>waitWhile: aBlock for: aSymbol
Confitional waiting for the non-default event represented by the argument symbol.
Same as Monitor>>waitWhile:for:, but the process gets only reactivated by the specific event and not the default event.
Monitor>>waitUntil: aBlock for: aSymbol
Confitional waiting for the non-default event represented by the argument symbol.
See Monitor>>waitWhile:for: aBlock.
Monitor>>signal: aSymbol
One process waiting for the given event is woken up. If there is no process waiting for this specific event, a process waiting for the default event gets resumed.
Monitor>>signalAll: aSymbol
All process waiting for the given event or the default event are woken up.
Monitor>>signalReallyAll
All processes waiting for any events (default or specific) are woken up.
Using timeouts
Monitor>>waitMaxMilliseconds: anInteger
Monitor>>waitFor: aSymbol maxMilliseconds: anInteger
Same as Monitor>>wait (resp. Monitor>>waitFor:), but the process gets automatically woken up when the specified time has passed.
Monitor>>waitWhile: aBlock maxMilliseconds: anInteger
Monitor>>waitWhile: aBlock for: aSymbol maxMilliseconds: anInteger
Same as Monitor>>waitWhile: (resp. Monitor>>waitWhile:for:), but the process gets automatically woken up when the specified time has passed.
Monitor>>waitUntil: aBlock maxMilliseconds: anInteger
Monitor>>waitUntil: aBlock for: aSymbol maxMilliseconds: anInteger
Same as Monitor>>waitUntil: (resp. Monitor>>waitUntil:for:), but the process gets automatically woken up when the specified time has passed.!
Item was changed:
----- Method: Monitor>>checkOwnerProcess (in category 'private') -----
checkOwnerProcess
"If the receiver is not already the owner of the section raise an error."
+
+ self primitiveTestAndSetOwnershipOfCriticalSection ifNotNil: [ :alreadyOwner |
+ alreadyOwner ifTrue: [ ^self ].
+ self primitiveExitCriticalSection ].
+ self error: 'Monitor access violation'!
- (self primitiveTestAndSetOwnershipOfCriticalSection
- ifNil: [false]
- ifNotNil:
- [:alreadyOwner|
- alreadyOwner
- or: [self primitiveExitCriticalSection.
- false]]) ifFalse:
- [self error: 'Monitor access violation']!
Item was removed:
- ----- Method: Monitor>>critical: (in category 'mutual exclusion') -----
- critical: aBlock
- "Evaluate aBlock protected by the receiver."
- <criticalSection>
- ^self primitiveEnterCriticalSection
- ifTrue: [aBlock value]
- ifFalse: [aBlock ensure: [self primitiveExitCriticalSection]]!
Item was removed:
- ----- Method: Monitor>>critical:ifLocked: (in category 'mutual exclusion') -----
- critical: aBlock ifLocked: lockedBlock
- "Answer the evaluation of aBlock protected by the receiver. If it is already in a critical
- section on behalf of some other process answer the evaluation of lockedBlock."
- <criticalSection>
- ^self primitiveTestAndSetOwnershipOfCriticalSection
- ifNil: [lockedBlock value]
- ifNotNil:
- [:alreadyOwner|
- alreadyOwner
- ifTrue: [aBlock value]
- ifFalse: [aBlock ensure: [self primitiveExitCriticalSection]]]!
Item was changed:
----- Method: Monitor>>initialize (in category 'initialize-release') -----
initialize
+ queuesMutex := Mutex new!
- queuesMutex := Semaphore forMutualExclusion!
Item was removed:
- ----- Method: Monitor>>primitiveEnterCriticalSection (in category 'private-primitives') -----
- primitiveEnterCriticalSection
- "Primitive. The receiver must be unowned or owned by the current process to proceed.
- Answer if the process is owned by the current process.
-
- Copyright (c) 2016 - 3D Immersive Collaboration Consulting, LLC."
- <primitive: 186>
- self primitiveFailed
- "In the spirit of the following"
- "[owner ifNil:
- [owner := Processor activeProcess.
- ^false].
- owner = Processor activeProcess ifTrue:
- [^true].
- self addLast: Processor activeProcess.
- Processor activeProcess suspend] valueUnpreemptively"!
Item was removed:
- ----- Method: Monitor>>primitiveExitCriticalSection (in category 'private-primitives') -----
- primitiveExitCriticalSection
- "Primitive. Set the receiver to unowned and if any processes are waiting on
- the receiver then proceed the first one, indicating that the receiver is unowned.
-
- Copyright (c) 2016 - 3D Immersive Collaboration Consulting, LLC."
- <primitive: 185>
- self primitiveFailed
- "In the spirit of the following"
- "[owner := nil.
- self isEmpty ifFalse:
- [process := self removeFirst.
- process resume]] valueUnpreemptively"!
Item was removed:
- ----- Method: Monitor>>primitiveTestAndSetOwnershipOfCriticalSection (in category 'private-primitives') -----
- primitiveTestAndSetOwnershipOfCriticalSection
- "Primitive. Attempt to set the ownership of the receiver.
- If the receiver is unowned set its owningProcess to the
- activeProcess and answer false. If the receiver is owned
- by the activeProcess answer true. If the receiver is owned
- by some other process answer nil.
-
- Copyright (c) 2016 - 3D Immersive Collaboration Consulting, LLC."
- <primitive: 187>
- self primitiveFailed
- "In the spirit of the following"
- "[owner ifNil:
- [owningProcess := Processor activeProcess.
- ^false].
- owner = Processor activeProcess ifTrue: [^true].
- ^nil] valueUnpreemptively"!
Levente Uzonyi uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-ul.783.mcz
==================== Summary ====================
Name: Collections-ul.783
Author: ul
Time: 5 March 2018, 10:52:44.810023 pm
UUID: 3cb7824b-9833-4ab9-bbac-66e36049b6ed
Ancestors: Collections-ul.782
WeakIdentityKeyDictionary changes:
- implemented #slowSize to be able to count of actually stored associations
- overridden #compact to cut tally back based on #slowSize
- compact the dictionary after removing unreferenced keys in #removeUnreferencedKeys
This all will ensure that if Undeclared is empty, then #isEmpty will return true after Smalltalk cleanOutUndeclared is executed.
=============== Diff against Collections-ul.782 ===============
Item was added:
+ ----- Method: WeakIdentityDictionary>>compact (in category 'private') -----
+ compact
+ "Reduce the size of array so that the load factor will be ~75%."
+
+ | newCapacity |
+ tally := self slowSize.
+ newCapacity := self class goodPrimeAtLeast: tally * 4 // 3.
+ self growTo: newCapacity!
Item was added:
+ ----- Method: WeakIdentityDictionary>>removeUnreferencedKeys (in category 'as yet unclassified') -----
+ removeUnreferencedKeys
+ "Make sure tally is set to the right size by #compact."
+
+ super removeUnreferencedKeys.
+ self compact!
Item was added:
+ ----- Method: WeakIdentityDictionary>>slowSize (in category 'accessing') -----
+ slowSize
+ "Careful!! Answer the maximum amount
+ of elements in the receiver, not the
+ exact amount"
+
+ | count |
+ count := 0.
+ 1 to: array size do: [ :index |
+ (array at: index) ifNotNil: [ :object |
+ object == vacuum ifFalse: [
+ count := count + 1 ] ] ].
+ ^count!