Operating System - OpenVMS
1753835 Members
7806 Online
108806 Solutions
New Discussion юеВ

Re: SYS$QIOW doesn't return to caller

 
Antoniov.
Honored Contributor

SYS$QIOW doesn't return to caller

Hello to anybody,
I've a problem that sometimes disturb me.
I use in C programs SYS$QIOW system service to various mode; it works fine but sometime process stay always waiting.
For example, I use a my detached process that send data to a printer via terminal server; if printer is disconnect during printing detached process it happpens.
Also using mailbox to comunicate between two processes, if one process hang, other process stay always in waiting mode.
I read this can happen because system service is waiting for event flag.
Question:
Why does happen it?
And how I can solve?
This problem is very fastidious in process intercomunication.

Thanks to all.
Antoniov
Antonio Maria Vigliotti
8 REPLIES 8
Ian Miller.
Honored Contributor

Re: SYS$QIOW doesn't return to caller

if you want the QIOW to eventually time out and that facility is not available (for some e.g TTDRIVER it is) then it is possbile to set a timer with an AST. The AST checks the IOSB of the QIO to ensure it has not completed (status is 0 i.e. SS$_PENDING) and if so cancells the QIO using SYS$CANCEL and sets a flag (so the program knows the timeout AST did cancel the I/O rather than another reason). The QIOW completes and the mainline code can workout what happend.
____________________
Purely Personal Opinion
Antoniov.
Honored Contributor

Re: SYS$QIOW doesn't return to caller

Ian,
may be a good idea; can I use timeout when process write?
Is there no any way to force abrutly end of call from external?

Thanks.
Antonio Maria Vigliotti
Ian Miller.
Honored Contributor

Re: SYS$QIOW doesn't return to caller

to terminate the QIOW from external to the program depends on what the device is. For a network connection then UCX DISCONNECT and NCP DISCONNECT are available.

For a program waiting on a mailbox you can use DCL to open the mailbox and write some data to the mailbox. Neil Clift's MBOX utility (from HG fileserv) may be useful.
Also http://h71000.www7.hp.com/freeware/freeware60/crembx/
____________________
Purely Personal Opinion
John Gillings
Honored Contributor

Re: SYS$QIOW doesn't return to caller

Antoniov,

Some drivers allow the IO$M_TIMED modifier to specify a timeout for the $QIO.

If it's not supported for your particular operation (for example, mailbox I/O), you can implement it yourself using "crossed ASTs". Start a timer with AST completion that cancels the I/O. The I/O then has a completion AST that cancels the timer. Use the channel number as the timer ID. Roughly speaking:
(details of argument types and mechanisms in your choice of language left as an exercise):

TimeExpiredAST(Chan)
$CANCEL(Chan)
END

IOCompleteAST(Timer)
$CANTIM(Timer)
END

...
Stat=$SETIMR(EFN$C_ENF,Timeout,
TimeExpiredAST,Chan)
Stat=$QIOW(EFN$C_ENF,Chan,func,IOSB,
IOCompleteAST,Chan,p1...)
check IOSB to work out what happened
...

I've used the "non-event flag", you can specify the same or different EFNs if you like event flags.

You can use $QIO rather than $QIOW if you have other stuff to do, but eventually you'll need to $SYNCH to determine when the I/O completes (or use the I/O completion AST to process the I/O)

There may be some circumstances where the I/O still blocks, regardless of the timeout. Check the driver documentation. For example, on mailbox I/Os add IO$M_NOW and/or IO$M_NORSWAIT to avoid most cases where the I/O might block. (and don't forget to code for the resulting conditions!)


Answering your specific question...

>Why does happen it?
>And how I can solve?

you need to be very careful how event flags are used across the whole process. It's possible to "lose" a $SETEF. In general you should use $SYNCH to test for I/O completion - see the documentation of $SYNCH for an explanation of the algorithm used. Bottom line is "always leave an event flag set after use" and "always have a secondary method to double check the status of the event".

For mailbox I/O, the default is for the writer to wait until the reader has read the message. Use IO$M_NOW to continue immediately after writing the message.

Another possibility is a resource wait. If a mailbox is full you could be stuck in RWMBX. Use IO$M_NORSWAIT to fail with SS$_MBFULL instead.
A crucible of informative mistakes
Antoniov.
Honored Contributor

Re: SYS$QIOW doesn't return to caller

John,
thanks very much for your detailed explain.
I use C language; I've already used $CANCEL and $CANTIM and never used event flag, SYS$QIO in congiuntion with SYNCH.
In mbx I don't remember IO$M_NOW and/or IO$M_NORSWAIT flag so I'll look in my documentation for furthermore details.
Most common troubles are two:
1) when a detached process (that's a particulary printer server) send data to a LAT port and printer is disconnected, it waits for output completation; I have to kill.
2) I use some internal intercomunication with mailbox; there is a message server detach process (software is 15 years old); in some circumstance some process stucks and all comunication are stopped because server remain infinitly for completation read. So I need to kill all processes and restart comunication system: very very bad.

I hope find a solution without modify software but now I think it's better review the code.

Thanks for furthermore ideas.
Antoniov
Antonio Maria Vigliotti
Martin Kirby
Advisor

Re: SYS$QIOW doesn't return to caller

I think John's solution is not safe in a multi-threaded program with upcalls.

The following sequence can occur:

Another thread disables ASTs.
The QIOW completes
The IoCompleteAST is queued but not executed
The Timer completes
The TimerAST is queued but not executed
The channel is use for some other purpose, deassigned, or a new QIO started.
The other thread reenables AST

The ASTs are executed in order. Normally, the $CANTIM would remove the unexecuted timer ast. However, that doesn't happen when upcalls are in use as the ast will have been removed from the normal list to pthread's. The TimerAST then tramples on the reused channel.

Having fallen foul of a similar issue with $CANTIM not preventing execution of an already queued timer ast I am now nervous about using timer asts.

Of course, if you know your program is not multi-threaded then this isn't an issue for you.

Martin Kirby
Willem Grooters
Honored Contributor

Re: SYS$QIOW doesn't return to caller

Antonio,
Long time ago I used a solution like John sufggested for the very same reason you have.
Only, I used two evenflags (1 for QIOW and 2 for the timer) and issued $WFLOR (Wait for any local flag of 1 OR 2). Both QUIW and SETTMR had AST that set the appropiate flag, so I could determine what caused the fall-through of $WFLOR: QIOW (so it was succesful) of timer (what meant failure).
Point is the printer should respond within say 5 secons and if not, I could take it off-line (logically, within the program) and signal the failure without disrupting normal processing. This was done within a detached program (which in turn got his messages from an exception handler...)

Willem
Willem Grooters
OpenVMS Developer & System Manager
Antoniov.
Honored Contributor

Re: SYS$QIOW doesn't return to caller

Martin,
thanks for warning; mi software is very old and doesn't use thread.
Willen,
thanks for suggestion; I can't modify software this week so I think updgrade next one.

Antoniov

Antonio Maria Vigliotti