diff options
author | jeff <jeff@FreeBSD.org> | 2007-12-16 06:21:20 +0000 |
---|---|---|
committer | jeff <jeff@FreeBSD.org> | 2007-12-16 06:21:20 +0000 |
commit | 4ec9caf00c407884fc51ff18adb8ff16a5eb75c0 (patch) | |
tree | e3b97a4fccf98fcc3311ea54b086b57edb1abb4d /sys/netncp/ncp_rq.c | |
parent | 436e8270ebc964cc1f1effe79ac5c10e92e78f7b (diff) | |
download | FreeBSD-src-4ec9caf00c407884fc51ff18adb8ff16a5eb75c0.zip FreeBSD-src-4ec9caf00c407884fc51ff18adb8ff16a5eb75c0.tar.gz |
Refactor select to reduce contention and hide internal implementation
details from consumers.
- Track individual selecters on a per-descriptor basis such that there
are no longer collisions and after sleeping for events only those
descriptors which triggered events must be rescaned.
- Protect the selinfo (per descriptor) structure with a mtx pool mutex.
mtx pool mutexes were chosen to preserve api compatibility with
existing code which does nothing but bzero() to setup selinfo
structures.
- Use a per-thread wait channel rather than a global wait channel.
- Hide select implementation details in a seltd structure which is
opaque to the rest of the kernel.
- Provide a 'selsocket' interface for those kernel consumers who wish to
select on a socket when they have no fd so they no longer have to
be aware of select implementation details.
Tested by: kris
Reviewed on: arch
Diffstat (limited to 'sys/netncp/ncp_rq.c')
-rw-r--r-- | sys/netncp/ncp_rq.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/sys/netncp/ncp_rq.c b/sys/netncp/ncp_rq.c index b637c9a..38e3e54 100644 --- a/sys/netncp/ncp_rq.c +++ b/sys/netncp/ncp_rq.c @@ -43,6 +43,8 @@ __FBSDID("$FreeBSD$"); #include <sys/mbuf.h> #include <sys/poll.h> #include <sys/proc.h> +#include <sys/socket.h> +#include <sys/socketvar.h> #include <sys/uio.h> #include <netncp/ncp.h> @@ -274,7 +276,9 @@ ncp_request_int(struct ncp_rq *rqp) /* * Flush out replies on previous reqs */ - while (ncp_poll(so, POLLIN) != 0) { + tv.tv_sec = 0; + tv.tv_usec = 0; + while (selsocket(so, POLLIN, &tv, td) == 0) { if (ncp_sock_recv(so, &m, &len) != 0) break; m_freem(m); @@ -319,7 +323,7 @@ ncp_request_int(struct ncp_rq *rqp) } tv.tv_sec = conn->li.timeout; tv.tv_usec = 0; - error = ncp_sock_rselect(so, td, &tv, POLLIN); + error = selsocket(so, POLLIN, &tv, td); if (error == EWOULDBLOCK ) /* timeout expired */ continue; error = ncp_chkintr(conn, td); @@ -335,7 +339,9 @@ ncp_request_int(struct ncp_rq *rqp) dosend = 1; /* resend rq if error */ for (;;) { error = 0; - if (ncp_poll(so, POLLIN) == 0) + tv.tv_sec = 0; + tv.tv_usec = 0; + if (selsocket(so, POLLIN, &tv, td) != 0) break; /* if (so->so_rcv.sb_cc == 0) { break; |