src/JavaMonitor.st
author hlopkmar
Mon, 28 Nov 2011 13:03:05 +0000
branchjk_new_structure
changeset 1169 8f727dc66647
parent 1159 afe8ab363ca3
child 1172 7795b5618017
permissions -rw-r--r--
monitor fix.. many to come :)

"
 COPYRIGHT (c) 1996-2011 by Claus Gittinger

 New code and modifications done at SWING Research Group [1]:

 COPYRIGHT (c) 2010-2011 by Jan Vrany, Jan Kurs and Marcel Hlopko
                            SWING Research Group, Czech Technical University in Prague

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.

 [1] Code written at SWING Research Group contains a signature
     of one of the above copright owners. For exact set of such code,
     see the differences between this version and version stx:libjava
     as of 1.9.2010
"
"{ Package: 'stx:libjava' }"

Object subclass:#JavaMonitor
	instanceVariableNames:'owningProcess processesEntered monitorSema processesEnteredAccess
		owningProcessAccess count countAccess waitingSema
		processesWaitingAccess processesWaiting'
	classVariableNames:''
	poolDictionaries:''
	category:'Languages-Java-Support'
!

!JavaMonitor class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1996-2011 by Claus Gittinger

 New code and modifications done at SWING Research Group [1]:

 COPYRIGHT (c) 2010-2011 by Jan Vrany, Jan Kurs and Marcel Hlopko
                            SWING Research Group, Czech Technical University in Prague

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.

 [1] Code written at SWING Research Group contains a signature
     of one of the above copright owners. For exact set of such code,
     see the differences between this version and version stx:libjava
     as of 1.9.2010

"
! !

!JavaMonitor class methodsFor:'instance creation'!

new
^self basicNew initialize.

    "Created: / 20-11-2011 / 14:30:36 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
! !

!JavaMonitor methodsFor:'accessing'!

activeProcess
    ^ Processor activeProcess
!

copyProcessesEntered
    ^ processesEntered copy.

    "Created: / 20-11-2011 / 14:45:24 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

processesEntered
    "dont do anything to me, access needs to be sync'd"
    ^ processesEntered.

    "Created: / 20-11-2011 / 13:22:15 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
! !

!JavaMonitor methodsFor:'atomic'!

addProcess: aProcess
    processesEnteredAccess critical: [processesEntered add: aProcess].

    "Created: / 20-11-2011 / 20:30:07 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

clearOwningProcess
    owningProcessAccess critical: [ owningProcess := nil ].

    "Created: / 20-11-2011 / 20:34:27 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

decrement
    "owning process released monitor, lets lower our counter so we know how many times
     do we have to release it"
    
    countAccess critical: [ count := count - 1 ].

    "Created: / 22-11-2011 / 10:49:33 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

increment
    "owning process entered monitor again (recursion ...), lets raise our counter so we know how many times
    do we have to release it"
    countAccess critical: [ count := count + 1 ].

    "Created: / 22-11-2011 / 10:49:07 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

owningProcess: aProcess
owningProcessAccess critical: [owningProcess := aProcess].

    "Created: / 20-11-2011 / 20:32:26 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

processesWaitingAdd: aProcess 
    processesWaitingAccess 
        critical: [ self assert: (processesWaiting includesKey: aProcess) not.processesWaiting at: aProcess put: count ].

    "Created: / 22-11-2011 / 11:57:50 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

processesWaitingRestore: aProcess 
   processesWaitingAccess 
   critical: [
   self assert: (processesWaiting includesKey: aProcess).
   self reinitCounter: (processesWaiting at: aProcess).   
   processesWaiting removeKey: aProcess
           ].

    "Created: / 22-11-2011 / 12:59:14 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

reinitCounter
    "owning process is different from previous, lets start counting from beginning"
    
    countAccess critical: [ count := 1 ].

    "Created: / 22-11-2011 / 10:51:09 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

reinitCounter: newCount 
    countAccess critical: [ count := newCount ].

    "Created: / 22-11-2011 / 13:00:51 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

removeProcess: aProcess 
    processesEnteredAccess 
        critical: [
            self assert: processesEntered last == aProcess.
            processesEntered remove: aProcess
        ].

    "Created: / 20-11-2011 / 20:28:37 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
! !

!JavaMonitor methodsFor:'initialization'!

initialize
    owningProcess := nil.
    owningProcessAccess := Semaphore forMutualExclusion.
    processesEntered := OrderedCollection new.
    processesEnteredAccess := Semaphore forMutualExclusion.
    monitorSema := Semaphore new: 1.
    countAccess := Semaphore forMutualExclusion.
    processesWaiting := Dictionary new.
    processesWaitingAccess := Semaphore forMutualExclusion.
    waitingSema := Semaphore new: 0.

    "Created: / 20-11-2011 / 13:28:28 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
! !

!JavaMonitor methodsFor:'public'!

acquire
    | thisProcess |
    thisProcess := self activeProcess.
    (self isOwnedBy: thisProcess) ifTrue: [
        self increment.
        ^ self
    ].
    monitorSema wait.
    self owningProcess: thisProcess.
    self reinitCounter.

    "Created: / 20-11-2011 / 13:21:46 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

enter
    | thisProcess |
    thisProcess := self activeProcess.
    self addProcess: thisProcess.
    self acquire.

    "Created: / 20-11-2011 / 13:21:42 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

exit
    | thisProcess |
    thisProcess := self activeProcess.
    (self isOwnedBy: thisProcess) ifTrue: [ self release. ].    
    processesEntered remove: thisProcess ifAbsent: nil.

    "Created: / 20-11-2011 / 13:21:54 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

notify
    "wakeup one waiting process"
    
    | thisProcess |
    thisProcess := Processor activeProcess.
    self assert: (self isOwnedBy: thisProcess).        
    waitingSema signal.

    "Created: / 22-11-2011 / 12:14:23 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

notifyAll
    "wakeup one waiting process"
    
    | thisProcess |
    thisProcess := Processor activeProcess.
    self assert: (self isOwnedBy: thisProcess).
    waitingSema signalForAll.

    "Created: / 22-11-2011 / 12:14:36 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

release
    | thisProcess |
    thisProcess := self activeProcess.
    self assert: (self isOwnedBy: owningProcess).
    count == 1 ifTrue: [
        self clearOwningProcess.
        monitorSema signal.
    ] ifFalse: [
        self decrement.       
    ]

    "Created: / 20-11-2011 / 13:21:52 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

releaseAll
    count timesRepeat: [self release].

    "Created: / 22-11-2011 / 13:05:20 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

wait
    "make owning process to go to wait"
    
    self waitForMilliseconds: nil.

    "Created: / 22-11-2011 / 11:57:56 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

waitForMilliseconds: timeOut 
    "make owning process to go to wait, but not longer than timeout"
    
    | thisProcess |
    thisProcess := Processor activeProcess.
    self assert: (self isOwnedBy: thisProcess).
    self processesWaitingAdd: thisProcess.
    self releaseAll.
     "JV@2011-11-25: zero timeout means wait without timeout!!!!!!"
    timeOut == 0 ifTrue: [ waitingSema wait ] ifFalse: [
        waitingSema waitWithTimeoutMs: timeOut
    ].
    self acquire.
    self processesWaitingRestore: thisProcess.

    "Created: / 22-11-2011 / 12:52:45 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
    "Modified (comment): / 25-11-2011 / 18:30:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
    "Modified: / 28-11-2011 / 14:01:25 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
! !

!JavaMonitor methodsFor:'queries'!

isAcquired
    ^ owningProcessAccess critical: [owningProcess notNil].

    "Created: / 20-11-2011 / 13:22:26 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
!

isOwnedBy: aProcess 
    ^ owningProcessAccess critical: [ owningProcess == aProcess ].

    "Created: / 20-11-2011 / 13:23:14 / Marcel Hlopko <hlopkmar@fel.cvut.cz>"
! !

!JavaMonitor class methodsFor:'documentation'!

version_SVN
    ^ '$Id$'
! !