Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Ticket #279 (assigned defect)

Opened 17 years ago

Last modified 16 years ago

Broken SocketConduit.read() in non-blocking mode.

Reported by: dpc Assigned to: kris (accepted)
Priority: minor Milestone: 2.0
Component: Tango Version: trunk
Keywords: triage Cc: dawid.ciezarkiewicz@asn.pl

Description

In nonblocking mode calling SocketConduit?.read() seams to make connection closed and returns nothing.

As a workaround I was told to use Socket.receive().

Attachments

IConduit.diff (397 bytes) - added by rrichardson on 11/05/07 02:52:45.
SocketConduit.diff (0.9 kB) - added by rrichardson on 11/05/07 02:53:11.

Change History

02/12/07 21:58:40 changed by kris

  • status changed from new to assigned.

SocketConduit?.reader() doesn't currently do anything smart with the return value from the Socket. Anything <= than zero is considered Eof. Recently made passing an empty buffer be an exceptional condition, as a path toward solving this issue. We'll have to wait a bit to see how things pan out.

03/04/07 19:50:06 changed by kris

  • milestone changed from 1.0 to 2.0.

11/05/07 02:29:20 changed by rrichardson

It seems that the problem is that it needs to return 2 types of values: The first indicates that there is no data to be read currently the non-blocking (EAGAIN or EWOULDBLOCK) case. This returns -1 from recv or write.

The second indicates that the connection has gone bad. the (*defined below) case. This returns 0 on a recv or write. This should return a different indicator than eof. It is a very common occurrence in asynchronous or multithreaded programs which queue up events or waiting sockets, or apps which use EPoll and may never actually receive a hangup event.

In the case of a recv on a bad socket, the call will return 0. I could imagine that SocketConduit? doesn't want to return 0 on error, since it's probably a very valid case for other conduits.

I propose that for read and write. If a -1 is returned, we return Eof. If a 0 is returned, we return BadFd? (or some descriptive term indicating that the connection is no longer valid) It should be able to be safely defined as -2 or somesuch.

NOTE: There is a better workaround for this than using Socket.Receive. You can use tango.stdc.errno.getErrno() upon receiving a Eof from a SocketConduit?. For the hangup or bad file socket: ECONNABORTED ECONNRESET EINVAL ENETDOWN ENETRESET ENOTCONN ESHUTDOWN ETIMEDOUT

For the nonBlocking not ready event case, one would receive: EAGAIN EWOULDBLOCK (I think that those are defined to be the same thing on most systems)

Also note: errno is broken on a multithreaded system because it is an external global variable, your function may have just returned an error, but some other function in another thread could have errored and set errno to something else before your thread checks the value)

Note that this is a workaround. I don't think that the customer of SocketConduit?, a high level library, should have to be making low-level calls to check the errno value.

11/05/07 02:52:45 changed by rrichardson

  • attachment IConduit.diff added.

11/05/07 02:53:11 changed by rrichardson

  • attachment SocketConduit.diff added.

05/26/08 03:59:19 changed by kris

thanks rrichardson ... have not forgotten about this :)

  • what's a good way to fix the errno issue?
  • returning two error values doesn't jive with the rest of the package, I'm afraid. Not sure how to fix that :'(

05/30/08 17:29:23 changed by larsivi

  • keywords set to triage.