David Pacheco wrote:
Jeff Trawick wrote:
Nicolas Williams wrote:
On Wed, Aug 19, 2009 at 05:57:04PM -0700, David Pacheco wrote:
Nicolas Williams wrote:
To my reading you have these possible conditions:

- max == 0 and port_getn() returns 0 -> *nget will have been set to the
  number of events available.
Except when you hit 6455223. This unlikely case occurs when some events on the port are not deliverable to the calling thread (e.g., async i/o completion after a fork in the child process). This is not relevant to this discussion, but it's worth noting that there are multiple edge conditions not handled well by the current implementation.

Oh, ick.

- port_getn() returns 0, or it returns -1 && errno is one of ETIME,
  EINTR, or EBADFD -> events may have been consumed and placed in
  list[], and *nget will have been set to the number of consumed
  events.
EBADFD can't return with events.

Ah, I misread the code.  The same applies to EINTR, as you point out.

I don't understand the comment here about EINTR. As far as anyone knows, is it possible to get EINTR with an event, as David suggests in the previous e-mail? ("It's unlikely that EINTR would return with events because usually we'll bail out at line 1338, but maybe we can loop through it multiple times having consumed events the first time and gotten EINTR later. ")


I didn't look at the code closely enough to say for sure. I know that we sometimes call the port_getn() kernel function multiple times for a single port_getn syscall invocation. If we can leave a port_getn() function call having consumed some events but reenter in order to consume more, then you could get EINTR with events...

A crucial detail regarding the issue of events returned with EINTR:

Just because nget > 0 when port_getn() returns -1/EINTR doesn't mean you have an event. When port_getn() is interrupted with a signal generally and -1/EINTR is returned, it appears that nget isn't updated to anything meaningful. So my code sees nget == 1 and tries to process the event. If no event had ever been returned (list uninitialized), I crash because portev_user is NULL; if an event had been returned previously in that storage, I would try to process the same event again, and associate it again afterwards. (seen on S10U5, b111a, b123)

I may have to set portev_user to something unique before calling port_getn() then clear nget if -1/EINTR is returned but portev_user is unchanged. (The user arg to port_associate() is always non-NULL.)

Any thoughts on this aspect?

_______________________________________________
networking-discuss mailing list
networking-discuss@opensolaris.org

Reply via email to