Example 12.6. Method Write_Back
/* Method Write_Back */ use arg data /* Save data to be written */ reply 0 /* Tell the sender all was OK */ self~disk_write(data) /* Now write the data */
0. The caller of method Write_Back continues processing from this point; meanwhile, method Write_Back also continues processing.
nextline:
Example 12.7. Message to INFILE
mymsg = infile~start("READLINE") /* Gets message object to carry */
/* message to INFILE */
/* do other work */
nextline=mymsg~result /* Gets result from message object */
mymsg message object obtains the result and holds it until the sender requests it.
Example 12.8. Example of a Rexx Semaphore Class
/*******************************************************************************/
/* A Rexx Semaphore Class. */
/* */
/* This file implements a semaphore class in Rexx. The class is defined to */
/* the Global Rexx Environment. The following methods are defined for */
/* this class: */
/* init - Initializes a new semaphore. Accepts the following positional */
/* parameters: */
/* 'name' - global name for this semaphore */
/* if named default to set name in */
/* the class semDirectory */
/* noshare - do not define named semaphore */
/* in class semDirectory */
/* Initial state (0 or 1) */
/* setInitialState - Allow for subclass to have some post-initialization, */
/* and do setup based on initial state of semaphore */
/* Waiting - Is the number of objects waiting on this semaphore. */
/* Shared - Is this semaphore shared (Global). */
/* Named - Is this semaphore named. */
/* Name - Is the name of a named semaphore. */
/* setSem - Sets the semaphore and returns previous state. */
/* resetSem - Sets state to unSet. */
/* querySem - Returns current state of semaphore. */
/* */
/* SemaphoreMeta - Is the metaclass for the semaphore classes. This class is */
/* set up so that when a namedSemaphore is shared, it maintains these */
/* named/shared semaphores as part of its state. These semaphores are */
/* maintained in a directory, and an UNKNOWN method is installed on the */
/* class to forward unknown messages to the directory. In this way the */
/* class can function as a class and "like" a directory, so [] syntax can */
/* be used to retrieve a semaphore from the class. */
/* */
/* */
/* The following are in the subclass EventSemaphore. */
/* */
/* Post - Posts this semaphore. */
/* Query - Queries the number of posts since the last reset. */
/* Reset - Resets the semaphore. */
/* Wait - Waits on this semaphore. */
/* */
/* */
/* The following are in the subclass MutexSemaphore */
/* */
/* requestMutex - Gets exclusive use of semaphore. */
/* releaseMutex - Releases to allow someone else to use semaphore. */
/* NOTE: Currently anyone can issue a release (need not be the owner). */
/*******************************************************************************/
/* ============================================================================ */
/* === Start of Semaphore class. ===== */
/* ============================================================================ */
::class SemaphoreMeta subclass class
::method init
expose semDict
/* Be sure to initialize parent */
.message~new(self, .array~of("INIT", super), "a", arg(1,"a"))~send
semDict = .directory~new
::method unknown
expose semDict
use arg msgName, args
/* Forward all unknown messages */
/* to the semaphore dictionary */
.message~new(semDict, msgName, "a", args)~send
if var("RESULT") then
return result
else
return
::class Semaphore subclass object metaclass SemaphoreMeta
::method init
expose sem waits shared name
use arg semname, shr, state
waits = 0 /* No one waiting */
name = "" /* Assume unnamed */
shared = 0 /* Assume not shared */
sem = 0 /* Default to not posted */
if state = 1 Then /* Should initial state be set? */
sem = 1
/* Was a name specified? */
if VAR("SEMNAME") & semname \= "" Then Do
name = semname /* Yes, so set the name */
if shr \= "NOSHARE" Then Do /* Do we want to share this sem? */
shared = 1 /* Yes, mark it shared */
/* Shared add to semDict */
self~class[name] = self
End
End
self~setInitialState(sem) /* Initialize initial state */
::method setInitialState
/* This method intended to be */
nop /* overridden by subclasses */
::method setSem
expose sem
oldState = sem
sem = 1 /* Set new state to 1 */
return oldState
::method resetSem
expose sem
sem = 0
return 0
::method querySem
expose sem
return sem
::method shared
expose shared
return shared /* Return true 1 or false 0 */
::method named
expose name
/* Does semaphore have a name? */
if name = "" Then return 0 /* No, not named */
Else return 1 /* Yes, it is named */
::method name
expose name
return name /* Return name or "" */
::method incWaits
expose waits
waits = waits + 1 /* One more object waiting */
::method decWaits
expose Waits
waits = waits - 1 /* One object less waiting */
::method Waiting
expose Waits
return waits /* Return number of objects waiting */
/* ========================================================================== */
/* === Start of EventSemaphore class. === */
/* ========================================================================== */
::class EventSemaphore subclass Semaphore public
::method setInitialState
expose posted posts
use arg posted
if posted then posts = 1
else posts = 0
::method post
expose posts posted
self~setSem /* Set semaphore state */
posted = 1 /* Mark as posted */
reply
posts = posts + 1 /* Increase the number of posts */
::method wait
expose posted
self~incWaits /* Increment number waiting */
guard off
guard on when posted /* Now wait until posted */
reply /* Return to caller */
self~decWaits /* Cleanup, 1 less waiting */
::method reset
expose posts posted
posted = self~resetSem /* Reset semaphore */
reply /* Do an early reply */
posts = 0 /* Reset number of posts */
::method query
expose posts
/* Return number of times */
return posts /* Semaphore has been posted */
/* ========================================================================== */
/* === Start of MutexSemaphore class. === */
/* ========================================================================== */
::class MutexSemaphore subclass Semaphore public
::method setInitialState
expose owned
use arg owned
::method requestMutex
expose Owned
Do forever /* Do until we get the semaphore */
owned = self~setSem
if Owned = 0 /* Was semaphore already set? */
Then leave /* Wasn't owned; we now have it */
else Do
self~incWaits
guard off /* Turn off guard status to let */
/* others come in */
guard on when \Owned /* Wait until not owned and get */
/* guard */
self~decWaits /* One less waiting for MUTEX */
End
/* Go up and see if we can get it */
End
::method releaseMutex
expose owned
owned = self~resetSem /* Reset semaphore */
Note