- Community Home
- >
- Servers and Operating Systems
- >
- Operating Systems
- >
- Operating System - OpenVMS
- >
- UDP programming - how to specify a read timeout us...
Categories
Company
Local Language
Forums
Discussions
Forums
- Data Protection and Retention
- Entry Storage Systems
- Legacy
- Midrange and Enterprise Storage
- Storage Networking
- HPE Nimble Storage
Discussions
Forums
Discussions
Discussions
Discussions
Forums
Discussions
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
- BladeSystem Infrastructure and Application Solutions
- Appliance Servers
- Alpha Servers
- BackOffice Products
- Internet Products
- HPE 9000 and HPE e3000 Servers
- Networking
- Netservers
- Secure OS Software for Linux
- Server Management (Insight Manager 7)
- Windows Server 2003
- Operating System - Tru64 Unix
- ProLiant Deployment and Provisioning
- Linux-Based Community / Regional
- Microsoft System Center Integration
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Discussion Boards
Community
Resources
Forums
Blogs
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-11-2014 08:09 AM
09-11-2014 08:09 AM
UDP programming - how to specify a read timeout using io$readvblk
Is it possible to specify a read timeout on a UDP socket
using a sys$qiow (IO$READVBLK) like one can do using select()/recv()
using C-socket programming style?
Do I need to call some sort of sys$qiow (IO$SETMODE) with an appropriate
item list?
Thanks a lot in advance.
Giovanni
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-11-2014 03:00 PM
09-11-2014 03:00 PM
Re: UDP programming - how to specify a read timeout using io$readvblk
Giovanni,
Some drivers implement a timeout option IO$M_TIMEOUT, some don't. If you haven't found it documented for your driver, you can assume your driver doesn't have one.
If that's the case, you can implement your own timeout using "crossed ASTs". The idea is to have a timer with an AST that cancels the I/O, and specify an AST on the I/O that cancels the timer. In pseudo code
$SETIMR daytim=TimeoutInterval astadr=CancelIO reqidt=MyTimer $QIOW chan=MyChan func=IO$READVBLK iosb=IOSB astadr=CancelTimer astprm=MyTimer (other parameters as required) routine CancelIO $CANCEL chan=MyChan end routine CancelTimer(timerID) $CANTIM reqidt=timerID end
After the $QIOW look at your IOSB. If it is successful, the I/O "won" the race, and the timer will have been cancelled. If the timer won, the IOSB will be SS$_CANCEL or SS$_ABORT, depending on how far the I/O had progressed. There are no race conditions, either the I/O will complete or it will get cancelled.
This mechanism also works for $QIO (asyncronous) I/Os, you just have to think a bit harder about the completion paths and how you manage them.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-11-2014 06:03 PM
09-11-2014 06:03 PM
Re: UDP programming - how to specify a read timeout using io$readvblk
From what I can tell of the documentation, there's no timeout available on the TCP/IP Services $qio IO$_READVBLK call.
As an alternative to the approach that Mr Gillings describes, you can also use $qio and ASTs and just leave the read hanging until something UDP happens, or until you're done with the networking.
It's entirely possible to issue these $qio reads in a self-requeuing loop, and where the AST passes the arriving packets off to the mainline code via an in-memory interlocked queue and (for instance) a $wake call, and the mainline processes until its done, and then issues a $hiber.
Put another way, it can be easier to use an aio-style asynchronous program on VMS, using ASTs and $hiber and $wake, rather than trying to mimic a synchronous sequence. (Threads can also work here, but mixing threads and ASTs is tricky, and TCP/IP Services $qio calls will mean you're using ASTs for at least some of your processing.)
Traditional wrinkles: packet sizes, fragmentation, applications getting "stuck" if a UDP message gets lost, and UDP messages can get lost.
$hiber and $wake wrinkles: if you use $hiber and $wake here, issue a $schdwk call as a backstop, and that'll force the mainline to wake up (maybe every 10 seconds or so) and check the queue — this is ugly, but can avoid a deadlock.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-12-2014 03:28 AM
09-12-2014 03:28 AM
Re: UDP programming - how to specify a read timeout using io$readvblk
First of all thanks to you and Mr Gillings for your answer and suggestion.
Coming to my original question, it look like it is possible to fill-in a socket-options descriptor like the following:
sockopt_itemlist.length = sizeof(tmo_itemlist);
sockopt_itemlist.type = TCPIP$C_SOCKOPT;
sockopt_itemlist.address = &tmo_itemlist;
pointing to an itemlist like
tmo_itemlist.length = sizeof(tmo);
tmo_itemlist.type = TCPIP$C_RCVTIMEO;
tmo_itemlist.address = &tmo;
where tmo is a structure containing seconds/microseconds you want to wait (pieces of codes I found
somewhare in this same blog).
Then I wonder if passing all this stuff to a call like the following, before calling the actual sys$qiow(IO$READVBLK), could do the trick.
status = sys$qiow(0, conn_channel, IO$_SETMODE, &iosb, 0, 0, 0, 0, &sockopt_itemlist, 0 );
Now, TCPIP$C_SOCKOPT should apply to both TCP and UDP sockets.
TCPIP$C_RCVTIMEO is described (in the TCPIP programming guide) as:
TCPIP$C_RCVTIMEO For HP use only . Sets the timeout value for a recv() operation. The argument is a pointer
to a timeval structure containing an integer value specified in second
(I'm a little bit worried about that "For HP use only").
Many thanks in advance for what you can elaborate on this.
Giovanni
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-12-2014 04:01 AM
09-12-2014 04:01 AM
Re: UDP programming - how to specify a read timeout using io$readvblk
Ask HP support directly.
With HP, things here probably weren't going to change all that much, so you could test that and then reasonably assume whatever current behavior was observed would probably persist. Now with VSI involved, it's anybody's guess what happens with the "reserved to..." stuff.
Or use the approaches that John and I have described, which are supported.
I've gotten burned by timeouts on more than a few occasions; races in the cancellation logic can be far too easy to create, and ugly to replicate. I've found it's much simpler to be AST-based, and to leave the $qio outstanding, and to detect when I don't care about the read response anymore within the code of the completion AST (via an interlocked bitflag or such), and to save the $cancel for when I'm shutting down the channel or the application.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-15-2014 02:19 AM
09-15-2014 02:19 AM
Re: UDP programming - how to specify a read timeout using io$readvblk
Hi !
http://starlet.deltatel.ru/~laishev/aaa-vms/pmas_radius.c
/* ** Prepare to timeout processing */ if ( !(1 & (status = sys$setimr(EFN$C_ENF, &delta_tmo,timer_ast,&reqidt,0))) ) break; /* ** Wait for an answer to request from RADIUS server */ if ( !(1 & (status = sys$qiow (EFN$C_ENF,chan,IO$_READVBLK,&netiosb,0,0, &ibuf,sizeof(ibuf),&rem_host,0,0,0))) ) break; /* ** Check status, byte count, and remote IP address */ if ( netiosb.iosb$w_bcnt && (netiosb.iosb$w_status & 1) && (auth_ans->radpkt$b_id == auth_req->radpkt$b_id) && sock_host.sin_addr.s_addr == ipaddr ) break; } sys$cantim(&reqidt,0);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-15-2014 10:57 AM
09-15-2014 10:57 AM
Re: UDP programming - how to specify a read timeout using io$readvblk
I like to work on VMS programs that use ASTs; I really do. AST-based code, when done correctly, is frequently more efficient and less prone to race-condition issues than any non-AST solution.
But I also recognize the fact that many users coming to VMS from other OSs may not be entirely comfortable using ASTs. So just in case you would prefer a non-AST solution, I have attached a C routine to this post routine as a .TXT file.
I wrote SYNCH_WITH_TIMEOUT.C back in 1993. Originally we used it for programs that did data-transfers using the terminal driver. Yes, I know that the VMS terminal driver has a built-in time-out function. See comments about that below.
Since then I have used it for many other applications, on Alpha and IA64, and it has always worked reliably.
A call to the synchronous SYS$QIOW() system service is documented as being identical to a call to the aynchronouse SYS$QIO() service followed immediately by a call to the SYS$SYNCH() service. My routine works just like SYS$SYNCH() but it has two additonal arguments. The I/O channel being used, and a F format floating point value for the timeout in units of seconds. (It would be easy to change the code to accept an integer value in .01 seconds units instead.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-15-2014 12:01 PM
09-15-2014 12:01 PM
Re: UDP programming - how to specify a read timeout using io$readvblk
Looks nice, Jess, but note that on Itanium with default compiler options that timeout will be S_FLOAT, not F_FLOAT, which might not do what you intended when passed to LIB$CVTF_TO_INTERNAL_TIME