SharedQueue.st
author claus
Mon, 08 Nov 1993 03:32:20 +0100
changeset 6 96ce41566060
parent 3 c9936b5a86a1
child 14 ca0b5fbc8131
permissions -rw-r--r--
2.8.1

"
 COPYRIGHT (c) 1993 by Claus Gittinger
              All Rights Reserved

 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.
"

Queue subclass:#SharedQueue
         instanceVariableNames:'accessProtect dataAvailable spaceAvailable'
         classVariableNames:''
         poolDictionaries:''
         category:'Collections-Ordered'!

SharedQueue comment:'
SharedQueues provide a safe mechanism for processes to communicate.

See samples in doc/coding.

$Header: /cvs/stx/stx/libbasic2/SharedQueue.st,v 1.4 1993-11-08 02:31:55 claus Exp $

'!

!SharedQueue methodsFor:'initialization'!

init:size
    super init:size.
    accessProtect := Semaphore forMutualExclusion.
    dataAvailable := Semaphore new.
    spaceAvailable := Semaphore new
! !

!SharedQueue methodsFor:'accessing'!

next
    "return the next value in the queue; if it its empty, wait 'til
     something is put into the receiver.
     When the datum has been removed, signal space-availability to
     writers"

    |value ok|

    ok := false.
    [ok] whileFalse:[
        [tally == 0] whileTrue:[
            dataAvailable wait
        ].
        accessProtect critical:[
            "
             this check is needed, since another process may
             have read the value in the meantime ...
            "
            tally == 0 ifFalse:[
                value := super next.
                tally == (contentsArray size - 1) ifTrue:[
                    spaceAvailable signal
                ].
                ok := true
            ]
        ]
    ].
    ^ value
!

nextPut:anObject
    "enter anObject into the queue; wait for available space, if
     the queue is full. After the put, signal availablity of a datum
     to readers."

    |ok|

    ok := false.
    [ok] whileFalse:[
        [tally == contentsArray size] whileTrue:[
            spaceAvailable wait
        ].
        accessProtect critical:[
            tally == contentsArray size ifFalse:[
                super nextPut:anObject.
                tally == 1 ifTrue:[
                    dataAvailable signal
                ].
                ok := true
            ]
        ]
    ].
    ^ anObject
! !