Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern In a case of direct select, set only masked events, ...
details: https://anonhg.NetBSD.org/src/rev/bc88ba118e60
branches: trunk
changeset: 762937:bc88ba118e60
user: rmind <rmind%NetBSD.org@localhost>
date: Sun Mar 06 04:41:58 2011 +0000
description:
In a case of direct select, set only masked events, do not wakeup LWP
if no polled/selected events were set; also, count the correct return
value for the select.
diffstat:
sys/kern/sys_select.c | 42 ++++++++++++++++++++++++++++++------------
1 files changed, 30 insertions(+), 12 deletions(-)
diffs (106 lines):
diff -r 470a0252b43c -r bc88ba118e60 sys/kern/sys_select.c
--- a/sys/kern/sys_select.c Sun Mar 06 04:34:25 2011 +0000
+++ b/sys/kern/sys_select.c Sun Mar 06 04:41:58 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_select.c,v 1.29 2010/12/18 01:36:19 rmind Exp $ */
+/* $NetBSD: sys_select.c,v 1.30 2011/03/06 04:41:58 rmind Exp $ */
/*-
* Copyright (c) 2007, 2008, 2009, 2010 The NetBSD Foundation, Inc.
@@ -84,7 +84,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_select.c,v 1.29 2010/12/18 01:36:19 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_select.c,v 1.30 2011/03/06 04:41:58 rmind Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -249,7 +249,7 @@
l->l_selret = 0;
if (op == SELOP_SELECT) {
- l->l_selbits = (char *)fds + ni * 3;
+ l->l_selbits = fds;
l->l_selni = ni;
} else {
l->l_selbits = NULL;
@@ -612,10 +612,11 @@
* sel_setevents: a helper function for selnotify(), to set the events
* for LWP sleeping in selcommon() or pollcommon().
*/
-static inline void
+static inline bool
sel_setevents(lwp_t *l, struct selinfo *sip, const int events)
{
const int oflag = l->l_selflag;
+ int ret = 0;
/*
* If we require re-scan or it was required by somebody else,
@@ -623,32 +624,45 @@
*/
if (__predict_false(events == 0 || oflag == SEL_RESET)) {
l->l_selflag = SEL_RESET;
- return;
+ return true;
}
/*
* Direct set. Note: select state of LWP is locked. First,
* determine whether it is selcommon() or pollcommon().
*/
if (l->l_selbits != NULL) {
+ const size_t ni = l->l_selni;
fd_mask *fds = (fd_mask *)l->l_selbits;
- const size_t ni = l->l_selni;
- const int fd = sip->sel_fdinfo;
+ fd_mask *ofds = (fd_mask *)((char *)fds + ni * 3);
+ const int fd = sip->sel_fdinfo, fbit = 1 << (fd & __NFDMASK);
const int idx = fd >> __NFDSHIFT;
int n;
for (n = 0; n < 3; n++) {
- if (sel_flag[n] & events) {
- fds[idx] |= 1 << (fd & __NFDMASK);
+ if ((fds[idx] & fbit) != 0 && (sel_flag[n] & events)) {
+ ofds[idx] |= fbit;
+ ret++;
}
fds = (fd_mask *)((char *)fds + ni);
+ ofds = (fd_mask *)((char *)ofds + ni);
}
} else {
struct pollfd *pfd = (void *)sip->sel_fdinfo;
- pfd->revents |= events;
+ int revents = events & (pfd->events | POLLERR | POLLHUP);
+
+ if (revents) {
+ pfd->revents |= revents;
+ ret = 1;
+ }
+ }
+ /* Check whether there are any events to return. */
+ if (!ret) {
+ return false;
}
/* Indicate direct set and note the event (cluster lock is held). */
l->l_selflag = SEL_EVENT;
- l->l_selret++;
+ l->l_selret += ret;
+ return true;
}
/*
@@ -688,7 +702,11 @@
l = sip->sel_lwp;
oflag = l->l_selflag;
#ifndef NO_DIRECT_SELECT
- sel_setevents(l, sip, events);
+ if (!sel_setevents(l, sip, events)) {
+ /* No events to return. */
+ mutex_spin_exit(lock);
+ return;
+ }
#else
l->l_selflag = SEL_RESET;
#endif
Home |
Main Index |
Thread Index |
Old Index