; From: Dat Thuc Nguyen
; Date: Tue Jun 15 14:34:09 1999
; URL: http://www.smalltickle.com
;
; WE USE SEMAPHORES TO COORDINATE COMPUTING TASKS,
; SHARE RESOURCES, ETC.
; THE FOLLOWING SCRIPT DEFINES A SEMAPHORE CLASS.

;********************************************************
;    DEFINITION OF THE SEMAPHORE CLASS                  *
;********************************************************
define semaphore {
    _assign semaphore::\%1 0    ; Initialize semaphore with 0
    _define \%1 {
        semaphore::\%1 \v(macro) \%2
    }
}
;******************************************************
;    IMPLEMENTATION OF THE PUBLIC USAGE INTERFACE     *
;    OF THE SEMAPHORE CLASS                           *
;******************************************************
define semaphore::up {
    _assign semaphore::\%1 \feval(\m(semaphore::\%1) + 1)
    echo \m(semaphore::\%1)
}

define semaphore::down {
    _assign semaphore::\%1 \feval(\m(semaphore::\%1) - 1)
    echo \m(semaphore::\%1)
}

define semaphore::query {
    return \m(semaphore::\%1)      
}

;********************************************************
;    USAGE SAMPLES                                      *
;********************************************************
take semaphore.ksc
semaphore com_port                      ; Create a semaphore com_port

; In a user-defined function:
;
xif = \fexec(com_port query) 0 {        ; If resource is available
    com_port up                         ; Register for resource
    do_some_processing                  ; 
    com_port down                       ; Release resource
}

; In another user-defined function
;
xif = \fexec(com_port query) 0 {        ; If resource is available
    com_port up                         : register for resource
    if \fexec(do_something) {           ; If do_something completed
        com_port down                   ; Release resource
    } else {                            ; Keep resource, release later
        do_other                        ; do something else
    }
}


; The script above follows the Smalltalk model.
;  C++ programmer can easily extend the class usage interface as follows:
;
define semaphore::++ {
    _assign semaphore::\%1 \feval(\m(semaphore::\%1) + 1)
    echo \m(semaphore::\%1)
}

define semaphore::-- {
    _assign semaphore::\%1 \feval(\m(semaphore::\%1) - 1)
    echo \m(semaphore::\%1)
}

; This demonstrate that the C-Kermit interpreter can accomodate several
; preferences.
