Add #synchronized: method.
authorStefan Vogel <sv@exept.de>
Wed, 29 Jan 1997 10:40:34 +0100
changeset 2295 75eccb7762c1
parent 2294 ed349da6fa4e
child 2296 97eb35d5ce43
Add #synchronized: method.
Object.st
--- a/Object.st	Tue Jan 28 12:35:50 1997 +0100
+++ b/Object.st	Wed Jan 29 10:40:34 1997 +0100
@@ -10,6 +10,8 @@
  hereby transferred.
 "
 
+'From Smalltalk/X, Version:3.1.3 on 28-jan-1997 at 19:48:37'                    !
+
 nil subclass:#Object
 	instanceVariableNames:''
 	classVariableNames:'ErrorSignal HaltSignal MessageNotUnderstoodSignal
@@ -20,7 +22,7 @@
 		WarningSignal PrimitiveFailureSignal DeepCopyErrorSignal
 		AbortSignal ErrorRecursion Dependencies InfoPrinting
 		ActivityNotificationSignal InternalErrorSignal
-		NonWeakDependencies'
+		NonWeakDependencies SynchronizationSemaphores'
 	poolDictionaries:''
 	category:'Kernel-Objects'
 !
@@ -131,6 +133,7 @@
         InformationSignal
         WarningSignal
         DeepCopyErrorSignal
+        InternalErrorSignal
 
         AbortSignal      <Signal>       Signal raised by debugger, to abort a computation
                                         BUT, the debugger will only raise it if it is handled.
@@ -141,7 +144,21 @@
         ErrorRecursion   <Boolean>      controls behavior when recursive errors occur (i.e. 
                                         an error while handling an error).
 
-        Dependencies     <Dictionary>   keeps track of object dependencies
+        Dependencies     <WeakDependencyDictionary>  
+                                        keeps track of object dependencies.
+
+        InfoPrinting     <Boolean>      controls weather informational messages 
+                                        are printed.
+
+        ActivityNotificationSignal <QuerySignal> 
+                                         raised on #activityNotification:
+
+        NonWeakDependencies <Dictionary> keeps track of object dependencies.
+                                         Dependents stay alive.
+
+        SynchronizationSemaphores <WeakIdentityDictionary>
+                                         Semaphores for per-object-monitor.
+                                        
 
     [author:]
         Claus Gittinger
@@ -242,7 +259,10 @@
         ].
         NonWeakDependencies isNil ifTrue:[
             NonWeakDependencies := IdentityDictionary new.
-        ]
+        ].
+        SynchronizationSemaphores isNil ifTrue:[
+            SynchronizationSemaphores := WeakIdentityDictionary new.
+        ].
     ].
 
     "/ initialize InfoPrinting to the VM's infoPrint setting
@@ -252,6 +272,7 @@
     "Object initialize"
 
     "Modified: 9.1.1997 / 00:28:38 / cg"
+    "Modified: 28.1.1997 / 19:38:58 / stefan"
 ! !
 
 !Object class methodsFor:'Signal constants'!
@@ -4676,6 +4697,92 @@
     "
 ! !
 
+!Object methodsFor:'synchronized evaluation'!
+
+freeSynchronizationSemaphore    
+    "free synchronizationSemaphore. May be used, to save memory when
+     an object is no longer used synchronized."
+
+    |sema blocked|
+
+    sema := self synchronizationSemaphore.
+    sema notNil ifTrue:[
+        sema wait.              "/ get lock
+        self synchronizationSemaphore:nil.
+    ].
+
+    "
+     self synchronized:[].
+     self synchronizationSemaphore.
+     self freeSynchronizationSemaphore.
+    "
+
+    "Created: 28.1.1997 / 19:31:20 / stefan"
+    "Modified: 28.1.1997 / 19:47:55 / stefan"
+!
+
+synchronizationSemaphore
+    "return the synchronization semaphore for myself.
+     subclasses may redefine"
+
+    ^ SynchronizationSemaphores at:self ifAbsent:[].
+
+    "
+      self synchronizationSemaphore
+    "
+
+    "Modified: 28.1.1997 / 19:47:09 / stefan"
+!
+
+synchronizationSemaphore:aSemaphore
+    "set the synchronisationSemaphore for myself.
+     subclasses may redefine this method"
+
+    aSemaphore isNil ifTrue:[
+        "/ remove Semaphore
+        SynchronizationSemaphores removeKey:self ifAbsent:[].
+    ] ifFalse:[
+        SynchronizationSemaphores at:self put:aSemaphore.
+    ].
+
+    "Modified: 28.1.1997 / 19:37:48 / stefan"
+!
+
+synchronized:aBlock
+    "evaluate aBlock synchronized, i.e. use a monitor for this object"
+
+    |sema blocked|
+
+    sema := self synchronizationSemaphore.
+    sema isNil ifTrue:[
+        "There is no semaphore yet, try ist again with interrupts
+         blocked to avoid a race"
+
+        blocked := OperatingSystem blockInterrupts.
+        sema := self synchronizationSemaphore.
+        sema isNil ifTrue:[
+            "get a locked semaphore (with count = 0)"
+            sema := Semaphore new.  
+            self synchronizationSemaphore:sema.
+        ] ifFalse:[
+            sema wait
+        ] .
+        blocked ifFalse:[OperatingSystem unblockInterrupts].
+    ] ifFalse:[
+        sema wait.
+    ].
+    aBlock valueOnUnwindDo:[sema signal].
+    sema signal.
+
+    "
+       [Object synchronized:[Delay waitForSeconds:2. Transcript showCR:'1']] fork.
+       [Object synchronized:[Delay waitForSeconds:2. Transcript showCR:'2']] fork.
+    "
+
+    "Created: 28.1.1997 / 17:52:56 / stefan"
+    "Modified: 28.1.1997 / 19:29:37 / stefan"
+! !
+
 !Object methodsFor:'system primitives'!
 
 asOop
@@ -5564,6 +5671,6 @@
 !Object class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Object.st,v 1.169 1997-01-27 23:36:53 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Object.st,v 1.170 1997-01-29 09:40:34 stefan Exp $'
 ! !
 Object initialize!