summaryrefslogtreecommitdiffstats
path: root/sys/netsmb
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2007-12-16 06:21:20 +0000
committerjeff <jeff@FreeBSD.org>2007-12-16 06:21:20 +0000
commit4ec9caf00c407884fc51ff18adb8ff16a5eb75c0 (patch)
treee3b97a4fccf98fcc3311ea54b086b57edb1abb4d /sys/netsmb
parent436e8270ebc964cc1f1effe79ac5c10e92e78f7b (diff)
downloadFreeBSD-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/netsmb')
-rw-r--r--sys/netsmb/smb_trantcp.c80
1 files changed, 1 insertions, 79 deletions
diff --git a/sys/netsmb/smb_trantcp.c b/sys/netsmb/smb_trantcp.c
index 7bdf211..5e34943 100644
--- a/sys/netsmb/smb_trantcp.c
+++ b/sys/netsmb/smb_trantcp.c
@@ -95,84 +95,6 @@ nb_setsockopt_int(struct socket *so, int level, int name, int val)
}
static int
-nbssn_rselect(struct nbpcb *nbp, struct timeval *tv, int events,
- struct thread *td)
-{
- struct timeval atv, rtv, ttv;
- int ncoll, timo, error, revents;
-
- if (tv) {
- atv = *tv;
- if (itimerfix(&atv)) {
- error = EINVAL;
- goto done_noproclock;
- }
- getmicrouptime(&rtv);
- timevaladd(&atv, &rtv);
- }
- timo = 0;
- mtx_lock(&sellock);
-retry:
-
- ncoll = nselcoll;
- thread_lock(td);
- td->td_flags |= TDF_SELECT;
- thread_unlock(td);
- mtx_unlock(&sellock);
-
- /* XXX: Should be done when the thread is initialized. */
- TAILQ_INIT(&td->td_selq);
- revents = sopoll(nbp->nbp_tso, events, NULL, td);
- mtx_lock(&sellock);
- if (revents) {
- error = 0;
- goto done;
- }
- if (tv) {
- getmicrouptime(&rtv);
- if (timevalcmp(&rtv, &atv, >=)) {
- error = EWOULDBLOCK;
- goto done;
- }
- ttv = atv;
- timevalsub(&ttv, &rtv);
- timo = tvtohz(&ttv);
- }
- /*
- * An event of our interest may occur during locking a process.
- * In order to avoid missing the event that occurred during locking
- * the process, test P_SELECT and rescan file descriptors if
- * necessary.
- */
- thread_lock(td);
- if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) {
- thread_unlock(td);
- goto retry;
- }
- thread_unlock(td);
-
- if (timo > 0)
- error = cv_timedwait(&selwait, &sellock, timo);
- else {
- cv_wait(&selwait, &sellock);
- error = 0;
- }
-
-done:
- clear_selinfo_list(td);
-
- thread_lock(td);
- td->td_flags &= ~TDF_SELECT;
- thread_unlock(td);
- mtx_unlock(&sellock);
-
-done_noproclock:
- if (error == ERESTART)
- return 0;
- return error;
-}
-
-static int
nb_intr(struct nbpcb *nbp, struct proc *p)
{
return 0;
@@ -302,7 +224,7 @@ nbssn_rq_request(struct nbpcb *nbp, struct thread *td)
if (error)
return error;
TIMESPEC_TO_TIMEVAL(&tv, &nbp->nbp_timo);
- error = nbssn_rselect(nbp, &tv, POLLIN, td);
+ error = selsocket(nbp->nbp_tso, POLLIN, &tv, td);
if (error == EWOULDBLOCK) { /* Timeout */
NBDEBUG("initial request timeout\n");
return ETIMEDOUT;
OpenPOWER on IntegriCloud