I am attempting to use the sample semaphore file 'semcls.rex' as supplied by ooRexx v4.1.2 in the \samples directory. If I run the following code snippet:
The prolog of the class file contains the comments regarding the 'init' invocation:
/* init - initialize a new semaphore. Will accept the following positional *//* parameters: *//* 'name' - global name for this semaphore *//* if named default to set name in *//* the class semDirectory *//* noshare - don't define named semaphore *//* into class semDirectory *//* Inital state (0 or 1) */
In the above run of testSem I have embedded the contents of the 'semcls.rex' file so that all trace back messages will be emitted. The error 93 messages are emitted in either case.
I'm sure that this is probably a misunderstanding on my part and any help will is appreciated. Thanks!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I thought that the init() method was driven when the new() method was invoked. That was my first attempt and it resulted in the following error (using the above code segment):
3 *-* sHandl = .Semaphore~new( 'tstSem' )
Error 97 running D:\REXX\testSem.rex line 3: Object method not found
Error 97.1: Object ".SEMAPHORE" does not understand message "NEW"
Since I am experimenting with the semaphore class I do not have much more to show in the way of functional code, however I have attached the source file that I am playing with.
First off, the Semaphore class is not public. So when you do the requires in your program, the .Semaphore class is not visible. That's why you get the message about not understanding the message new.
The class is not intended to be used the way you are trying. Rather you are expected to use one of the subclasses provided. Change your code to:
/-- REXX Procedure: testSem --/
sHandl = .MutexSemaphore~new( 'tstSem' )
say 'requesting mutex'
sHandl~RequestMutex
Say 'got mutex, leaving now'
Exit 0
::Requires semcls.rex
You will get output similar to:
requesting mutex
got mutex, leaving now
Which is expected, but at least you will now be on the right track.
At the time you invoke RequestMutex(), nothing else is holding the mutex, so your code immediately gains the mutex and proceeds.
Now you just need to figure out what to do with a mutex.
Here is a simplistic program that shows a writer and a reader. You don't want the reader to read while the writer is writing. And vice versa. I'll also attach it.
/-- REXX Procedure: holdMutex.rex --/
sHandl = .MutexSemaphore~new( 'tstSem' )
say 'created mutex'
You can see that the reader never gets the mutex until the writer releases it.
You can see that neither the reader nor the writer, even though they want to write or want to read, can read or write until the other is finished. You never get 'reading' interspersed with 'writing'. Each reader finishes all 5 reads without the writer writing anything while the reader is reading.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks for clearing up the mystery. Since I'm relatively new to the OO part of Rexx I thought that I probably wasn't looking at the problem properly.
Your example code is largely what I wish to do with my code, with the exception that the "reader" and "writer" will be in infinite loops with a unique semaphore (EventSemaphore class) associated with each thread. [EDIT] The worker tasks will use a MutexSemaphore to control access to a common buffer [EDIT END]. There will be another concurrent "control" task that will post the worker semaphore when termination is required. When reactivating after the sleep interval, the worker tasks will simply query their semaphore to determine if it is time to wrap-up. The intent is to provide a server style function with external control. The ability to query a semaphore for the post count was the main reason for using "semcls.rex" in the first place.
So thanks for the help and I may be back again if I get stuck.
Last edit: Tim Tierney 2013-07-05
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am attempting to use the sample semaphore file 'semcls.rex' as supplied by ooRexx v4.1.2 in the \samples directory. If I run the following code snippet:
I receive the following error messages on the console:
The prolog of the class file contains the comments regarding the 'init' invocation:
In the above run of testSem I have embedded the contents of the 'semcls.rex' file so that all trace back messages will be emitted. The error 93 messages are emitted in either case.
I'm sure that this is probably a misunderstanding on my part and any help will is appreciated. Thanks!
To instantiate a new object, you, usually, use the new() method. You don't invoke the init() method yourself.
Change this:
sHandl = .Semaphore~init( "tstSem" )
to this:
sHandl = .Semaphore~new( "tstSem" )
and see what happens.
If you still have problems, add your entire program as an attachment so that someone can take a look at it.
I thought that the init() method was driven when the new() method was invoked. That was my first attempt and it resulted in the following error (using the above code segment):
Since I am experimenting with the semaphore class I do not have much more to show in the way of functional code, however I have attached the source file that I am playing with.
Hi Tim,
First off, the Semaphore class is not public. So when you do the requires in your program, the .Semaphore class is not visible. That's why you get the message about not understanding the message new.
The class is not intended to be used the way you are trying. Rather you are expected to use one of the subclasses provided. Change your code to:
/-- REXX Procedure: testSem --/
sHandl = .MutexSemaphore~new( 'tstSem' )
say 'requesting mutex'
sHandl~RequestMutex
Say 'got mutex, leaving now'
Exit 0
::Requires semcls.rex
You will get output similar to:
requesting mutex
got mutex, leaving now
Which is expected, but at least you will now be on the right track.
At the time you invoke RequestMutex(), nothing else is holding the mutex, so your code immediately gains the mutex and proceeds.
Now you just need to figure out what to do with a mutex.
Here is a simplistic program that shows a writer and a reader. You don't want the reader to read while the writer is writing. And vice versa. I'll also attach it.
/-- REXX Procedure: holdMutex.rex --/
sHandl = .MutexSemaphore~new( 'tstSem' )
say 'created mutex'
writer = .Writer~new(sHandl)
reader = .Reader~new(sHandl)
writer~work
-- Let the writer get started
j = SysSleep(.1)
reader~work
Exit 0
::Requires semcls.rex
::class 'Writer'
::method init
expose mtx
use arg mtx
::method write
expose mtx
say 'want to write, requsting mtx'
mtx~requestMutex
say 'Writer got mutex'
do i = 1 to 5
say 'writing' i
r = SysSleep(1)
end
say 'writer releasing mutex'
mtx~releaseMutex
::method work unguarded
reply 0
do 15
self~write
r = SysSleep(2)
end
::class 'Reader'
::method init
expose mtx
use arg mtx
::method read
expose mtx
say 'want to read, requsting mtx'
mtx~requestMutex
say 'Reader got mutex'
do i = 1 to 5
say 'reading' i
r = SysSleep(1)
end
say 'reader releasing mutex'
mtx~releaseMutex
::method work unguarded
reply 0
do 15
self~read
r = SysSleep(2)
end
Maybe I should have added a little explanation. If you look at the output from the example:
~~~~~~~~~~~~~~
created mutex
want to write, requsting mtx
Writer got mutex
writing 1
want to read, requsting mtx
writing 2
writing 3
writing 4
writing 5
writer releasing mutex
Reader got mutex
reading 1
reading 2
want to write, requsting mtx
reading 3
reading 4
reading 5
reader releasing mutex
Writer got mutex
writing 1
writing 2
want to read, requsting mtx
writing 3
writing 4
writing 5
writer releasing mutex
Reader got mutex
reading 1
reading 2
want to write, requsting mtx
reading 3
reading 4
reading 5
reader releasing mutex
Writer got mutex
~~~~~~~~~~~~
You can see that the reader never gets the mutex until the writer releases it.
You can see that neither the reader nor the writer, even though they want to write or want to read, can read or write until the other is finished. You never get 'reading' interspersed with 'writing'. Each reader finishes all 5 reads without the writer writing anything while the reader is reading.
Hi Mike,
Thanks for clearing up the mystery. Since I'm relatively new to the OO part of Rexx I thought that I probably wasn't looking at the problem properly.
Your example code is largely what I wish to do with my code, with the exception that the "reader" and "writer" will be in infinite loops with a unique semaphore (EventSemaphore class) associated with each thread. [EDIT] The worker tasks will use a MutexSemaphore to control access to a common buffer [EDIT END]. There will be another concurrent "control" task that will post the worker semaphore when termination is required. When reactivating after the sleep interval, the worker tasks will simply query their semaphore to determine if it is time to wrap-up. The intent is to provide a server style function with external control. The ability to query a semaphore for the post count was the main reason for using "semcls.rex" in the first place.
So thanks for the help and I may be back again if I get stuck.
Last edit: Tim Tierney 2013-07-05