Oz and Mozart Hackers Mailing List

Re: Please help: Trying to implement non-blocking connect in OS module


From: Konstantin Popov (kost@sics.se)
Date: Fri Dec 12 2003 - 10:31:38 CET


Dear Harmon,

as a very first shot I'd suggest to have a look at the
'OS.connectNonblocking' (which is actually used) and its
implementation 'unix_connect_nonblocking()' in unix.cc.

I take on record that we'd better document the thing in the next
release - thank you for dragging the issue up.

Cheers,

 --- Kostja.

>
> Hello all. I'm using OZ in a multithreaded network application where it
> is imperative that no thread cause the entire oz emulator to block.
>
> Unfortunately, as implemented, the "connect" function of the OS module
> will block the entire oz-emulator, in particular if the connection
> attempt is to a host that does not exist, or to a port on which there is
> no service.
>
> "connect" can be made to be non-blocking (at least in UNIX) using a
> method described in the book "Unix Network Programming, Vol. 1" by W.
> Richard Stevens (pp. 409-422).
>
> However, I'm having trouble implementing this in the OZ code. I'm
> certain that the osconnect() function in the file os.cc needs to be
> changed to the following:
>
>
> --- START CODE ---
> int osconnect(int s, struct sockaddr *addr, int namelen)
> {
> osBlockSignals();
>
> // MAKE 's' NON-BLOCKING
> int flags = fcntl(s, F_GETFL);
> fcntl(s, F_SETFL, flags | O_NDELAY);
>
> // "connect" WILL NOT BLOCK
> // "ret" WILL EITHER BE 0, INDICATING SUCCESSFUL connect,
> // OR -1, WITH errno SET TO "EINPROGESS", INDICATING THAT connect
> // IS NOT YET COMPLETE
> int ret = connect(s,addr,namelen);
>
> // MAKE 's' BLOCKING AGAIN (PROBABLY DOESN'T MATTER)
> fcntl(s, F_SETFL, flags); // MAKE '
>
> osUnblockSignals();
> return ret;
> }
> ---- END CODE ----
>
> Here's where I'm stuck:
>
> The function that calls osconnect, i.e. "unix_connectInet" in the
> "unix.cc" file, needs to be changed to detect errno == EINPROGRESS, and
> suspend the current thread until the file descriptor used in the connect
> becomes writeable. The needed changes are outlined below:
>
> --- START CODE ---
> OZ_BI_define(unix_connectInet,3,0)
> {
>
> // ...
>
> int ret = osconnect(s,(struct sockaddr *) &addr,sizeof(addr));
>
> // CONNECT SUCCESSFUL
> if (ret == 0) return PROCEED;
>
> // CONNECT STILL IN PROGRESS
> if (errno == EINPROGRESS) {
>
> // SET UP "nbConnectCheck" TO BE CALLED BY OZ SCHEDULER
> // WHEN 's' FILE DESCRIPTOR BECOMES WRITABLE
> OZ_registerWriteHandler(s, nbConnectCheck, 0);
>
> // HELP! NEED TO SOMEHOW SUSPEND THE CURRENT THREAD
> // AND HAVE IT RESUME WHEN 's' FILE DESCRIPTOR BECOMES WRITABLE.
> // ...
> }
>
> // BAD CONNECT
> Assert(errno != EINTR);
> RETURN_UNIX_ERROR("connect");
>
> } OZ_BI_end
>
>
> int nbConnectCheck(int s, void *) {
>
> // HELP! NEED TO RESUME THREAD THAT WAS SUSPENDED ABOVE.
>
> int error;
>
> // ONCE 's' FILE DESCRIPTOR IS WRITABLE, CHECK STATUS WITH getsockopt
> if ( getsockopt( s, SOL_SOCKET, SO_ERROR, &error, sizeof(error) ) <
> 0 ) {
> RETURN_UNIX_ERROR("connect");
> } else {
> return PROCEED;
> }
>
> }
> ---- END CODE ----
>
> Am I even on the right track here? Can someone tell me what to do, or
> point me in the right direction?
>
> Any help would be *greatly appreciated*.
>
> Thanks
>
> -- Dr. Harmon S. Nine
>
> -
> Please send submissions to hackers@mozart-oz.org
> and administriva mail to hackers-request@mozart-oz.org.
> The Mozart Oz web site is at http://www.mozart-oz.org/.
-
Please send submissions to hackers@mozart-oz.org
and administriva mail to hackers-request@mozart-oz.org.
The Mozart Oz web site is at http://www.mozart-oz.org/.



This archive was generated by hypermail 2b29.