"======================================================================
|
|   Semaphore Method Definitions
|
|   $Revision: 1.7.5$
|   $Date: 2000/05/28 16:56:52$
|   $Author: pb$
|
 ======================================================================"


"======================================================================
|
| Copyright 1988-92, 1994-95, 1999, 2000 Free Software Foundation, Inc.
| Written by Steve Byrne.
|
| This file is part of the GNU Smalltalk class library.
|
| The GNU Smalltalk class library is free software; you can redistribute it
| and/or modify it under the terms of the GNU Lesser General Public License
| as published by the Free Software Foundation; either version 2.1, or (at
| your option) any later version.
| 
| The GNU Smalltalk class library is distributed in the hope that it will be
| useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
| General Public License for more details.
| 
| You should have received a copy of the GNU Lesser General Public License
| along with the GNU Smalltalk class library; see the file COPYING.LESSER.
| If not, write to the Free Software Foundation, 59 Temple Place - Suite
| 330, Boston, MA 02111-1307, USA.  
|
 ======================================================================"


LinkedList subclass: #Semaphore
	   instanceVariableNames: 'signals'
	   classVariableNames: ''
	   poolDictionaries: ''
	   category: 'Language-Processes'
!

Semaphore comment: 
'My instances represent counting semaphores.  I provide methods for signalling
the semaphore''s availability, and methods for waiting for its availability.
I also provide some methods for implementing critical sections.  I currently
do not (because the underlying system does not) support asynchronous
signals, such as might be generated by C signals.' !


!Semaphore class methodsFor: 'instance creation'!

new
    "Answer a new semaphore"
    ^self basicNew initSemaphore
!

forMutualExclusion
    "Answer a new semaphore with a signal on it. These semaphores are a useful
     shortcut when you use semaphores as critical sections."
    ^self new
	signal;
	yourself
! !



!Semaphore methodsFor: 'mutual exclusion'!

critical: aBlock
    "Wait for the receiver to be free, execute aBlock and signal the receiver
     again. Return the result of evaluating aBlock.
     aBlock MUST NOT CONTAIN A RETURN!!!"
    | result |
    self wait.
    result := aBlock value.
    self signal.
    ^result
! !



!Semaphore methodsFor: 'private'!

initSemaphore
    signals := 0
!

signals
    "Answer the number of processes that can be accomodated or (if negative
     the number of waiting processes."

    "signals never goes below 0, even if there are waiting process. So
     - if 0 and 0 processes are waiting, the signal count is 0
     - if 0 and k processes are waiting, the signal count is -k
     - if >0, no processes must be waiting and the signal count is signals"
    ^signals - self size
! !
