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