Operating System - OpenVMS
1837033 Members
2866 Online
110111 Solutions
New Discussion

Mailbox read with timeout

 
Bob S._1
Occasional Contributor

Mailbox read with timeout

I have a set of client-server routines that I wrote a while back and now I want to add some features. One enhancement I would like to make is to have the read time-out after a certain amount of time (defined by the client routine).

My routines are simple. The client routine creates a mailbox and sends the mailbox information to the server mailbox along with all the other data. The server process reads its mailbox and, when done, writes the information to the clients mailbox. Problems occur when processes get hung up or are terminated - leaving processes waiting for messages that are not going to arrive.

My routines are in FORTRAN and communicate with the mailboxes using READ's and WRITES's. I have started using QIO's in some places.
11 REPLIES 11
Robert Gezelter
Honored Contributor

Re: Mailbox read with timeout

Bob,

If you are using QIO, you can certainly create a TIMER AST and kill the IO operation after a certain period of time has elapsed. Several years ago, I gave a presentation (at the Fall 1995 DECUS Symposium, see http://www.rlgsc.com/decus/usf95/index.html )on using ASTs,and this is just one of their many uses. When the IO completes, you will get an IOSB with an IO cancelled completion code.

I would also recommend that you consider using DECnet mailboxes. Even if you are not using DECnet on your network, DECnet within a node (which has never had a license fee) is a far safer vehicle for this type of application.

For one thing, there is no need to worry about dangling mailboxes, or the need to synchronize mailboxes. The DECnet logical link creates a bidirectional message connection, with automatic handling of the situations where one of the processes terminates, among other possibilities.

- Bob Gezelter, http://www.rlgsc.com
Richard J Maher
Trusted Contributor

Re: Mailbox read with timeout

Hi Bob,

I think you'll find and example of the silution you are looking for in the code attached to: -

http://forums1.itrc.hp.com/service/forums/questionanswer.do?threadId=1058548

There is a $setimr on the setmode wait_for_reader (I think?)

But what you're really after IMHO is unidirectional channels (examples in same code) and the reader/writer check function modifiers when doing i/o. That is, if there's no one there to read my message then return an error.

Regards Richard Maher
Robert Atkinson
Respected Contributor

Re: Mailbox read with timeout

Bob,
Ian Miller wrote some utilities for creating and managing mailboxes (http://www.encompasserve.org/~miller/), which includes read timeout.

You may be able to use these directly, or copy the code.

Rob.
Jim Lahman_1
Advisor

Re: Mailbox read with timeout

Rather than using an AST, we use event flags. First, a timer is setup with an event flag. Then, a mailbox read is done with an event flag.

Then, we wait for an event flag to be set.

So, it goes something like this...

CX Set event flag mask
EVF_MASK = 0
EVF_MASK = IBSET(EVF_MASK,(MOD(MSG_READ_LEF,32)))
EVF_MASK = IBSET(EVF_MASK,(MOD(TMR_LEF,32)))

CX Set timer event flag for initial scan
STAT = SYS$SETEF (%VAL(TMR_LEF))

CX Set up the timer
STAT = SYS$SETIMR (%VAL(EV_FLG),%REF(BINTIM%VAL(0),%VAL(TEMP_TIMER_ID),)

CX Set up the mailbox read
QSTAT = SYS$QIO (%VAL(EFN),%VAL(MBX_CHAN(MBXREF)),%VAL(RCODE),%REF(IOSB),,,,%REF(MSG),%VAL(MAX_MSG_SIZE),,,,,)

CX wait for message read to complete or timer to expire

STAT = SYS$WFLOR (%VAL(MSG_READ_LEF),%VAL(EVF_MASK))
Cheers!
Ian Miller.
Honored Contributor

Re: Mailbox read with timeout

I guess you check check which event flag and if the I/O has not finished then cancel it.
____________________
Purely Personal Opinion
GuentherF
Trusted Contributor

Re: Mailbox read with timeout

Instead of using a timeout mechanism you may be able to use readers/writers attribute when assigning a channel to the mailbox. See the I/O User's Ref. Manual under the Mailbox chapter.

With this the server would be immediately aware that the client mailbox is gone.

Would not solve the problem of a non-responding client still holding onto the mailbox.

/Guenther
David Jones_21
Trusted Contributor

Re: Mailbox read with timeout

Directional mailboxes are good for detecting 'broken pipe' situtations, but not for hung processes. I often do timeouts via timer ASTs issuing SYS$CANCEL on the I/O. One thing to watch for is that the device driver doesn't always complete cancelled I/Os with a SS$_CANCEL status. I can't recall if the mailbox driver does it, but some network drivers return either SS$_ABORT or SS$_CANCEL depending on the state they're in.
I'm looking for marbles all day long.
Bob S._1
Occasional Contributor

Re: Mailbox read with timeout

A few related questions before I close the thread and assign points...

I use LIB$GET_EF to get event flags. WFLOR assumes event flags in the same cluster (right?). Should I worry about GET_EF returning event flags in different clusters?

What's the best thing to check to see if it was the timer or the QIO that finished? If I initialize the the IO Status Block, will it remain unchanged if the QIO did not finish? Does it hurt anything to cancel both the timer and the QIO? I assume that there is a minute possibility that the timer and the QIO will finish so close that I could possibly miss something.
Robert Gezelter
Honored Contributor

Re: Mailbox read with timeout

Bob,

LIB$GET_EF is defined to return an event flag from "the process-wide pool".

If you are working with event flags and timers, you do need to worry about race conditions (which is why I always recommend ASTs in such situations).

The IOSB (which you should always use) is initialized to 0 by SYS$QIO (see Systems Services Reference Manual on OpenVMS www site). I would then check accordingly. It is quite possible that the timer will expire at or about the same time as the IO completes. Remember to deal correctly with BOTH system services, otherwise you will likely have bugs due to dangling pointers.

- Bob Gezelter, http:///www.rlgsc.com
John Gillings
Honored Contributor

Re: Mailbox read with timeout

>I use LIB$GET_EF to get event flags. WFLOR assumes event flags in the same cluster (right?). Should I worry about GET_EF returning event flags in different clusters?

Bob,

YES, you do need to worry about the flags being in the same cluster. You can't WFLOR across clusters. The simplest mechanism is to ask for THREE event flags (call LIB$GET_EF 3 times). Since there are only two clusters, there must be at least one pair in the same cluster. LIB$FREE_EF the extra.

That said, the "crossed ASTs" method avoids a lot of timing issues, as well as avoiding the limits inherent in using such a scarce resource as event flags.
A crucible of informative mistakes
Jess Goodman
Esteemed Contributor

Re: Mailbox read with timeout

I have attached a routine, SYNCH_WITH_TIMEOUT.C, that can be used after any SYS$QIO call instead of using SYS$SYNCH.

This routine can be used with drivers and I/O functions that don't
allow for timeout values, such as a IO$_WRITEVBLK to a terminal if
you want to timeout when the terminal is ed, or mailbox reads.

Arguments to this routine (all are required):
efn - (longword passed by value) the $QIO event flag argument.
iochan - (word passed by value) the $QIO I/O channel argument.
iosb - (quadword passed via reference) the $QIO IOSB argument.
timeout - (F float passed by value) the seconds before the I/O
will time out. If timeout <= 0 no timeout will occur.

If a timeout occurs SS$_TIMEOUT will be in the first word of IOSB.

Example of use in C (can be called from any language):

long stat;
long efn=1;
short iochan;
short iosb[4];
float timeout=5.0;
long iofunc=IO$_WRITEVBLK;
char buffer[80];
int bytes=80;
int synch_with_timeout( long efn, short channel, short *iosb,
float timeout);
...
stat = sys$qio( efn, iochan, iofunc, iosb, NULL, NULL,
buffer, bytes, NULL, NULL, NULL, NULL);
if ((stat&1) == 0) return(stat);
synch_with_timeout( efn, iochan, iosb, timeout);
return(iosb[1]);

This routine will work correctly even if it is used with more
than one active asynchronouse I/O, as long as each active I/O
uses its own event flag and IOSB. It doesn't even use ASTs.
I have one, but it's personal.