Index: kern_event.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_event.c,v retrieving revision 1.47 diff -u -r1.47 kern_event.c --- kern_event.c 29 Oct 2002 20:51:44 -0000 1.47 +++ kern_event.c 3 Dec 2002 20:14:44 -0000 @@ -383,8 +383,8 @@ TAILQ_INIT(&kq->kq_head); fp->f_data = kq; FILE_UNLOCK(fp); - FILEDESC_LOCK(fdp); td->td_retval[0] = fd; + FILEDESC_LOCK(fdp); if (fdp->fd_knlistsize < 0) fdp->fd_knlistsize = 0; /* this process has a kq */ FILEDESC_UNLOCK(fdp); @@ -953,25 +953,23 @@ static void knote_attach(struct knote *kn, struct filedesc *fdp) { - struct klist *list, *oldlist, *tmp_knhash; + struct klist *list, *tmp_knhash; u_long tmp_knhashmask; - int size, newsize; + int size, fd_knlistsize; FILEDESC_LOCK(fdp); - if (! kn->kn_fop->f_isfd) { + if (!kn->kn_fop->f_isfd) { if (fdp->fd_knhashmask == 0) { FILEDESC_UNLOCK(fdp); tmp_knhash = hashinit(KN_HASHSIZE, M_KQUEUE, &tmp_knhashmask); FILEDESC_LOCK(fdp); - if (fdp->fd_knhashmask == 0) { + if ((volatile u_long)fdp->fd_knhashmask == 0) { fdp->fd_knhash = tmp_knhash; fdp->fd_knhashmask = tmp_knhashmask; } else { - FILEDESC_UNLOCK(fdp); free(tmp_knhash, M_KQUEUE); - FILEDESC_LOCK(fdp); } } list = &fdp->fd_knhash[KN_HASH(kn->kn_id, fdp->fd_knhashmask)]; @@ -979,7 +977,6 @@ } if (fdp->fd_knlistsize <= kn->kn_id) { -retry: size = fdp->fd_knlistsize; while (size <= kn->kn_id) size += KQEXTENT; @@ -987,31 +984,23 @@ MALLOC(list, struct klist *, size * sizeof(struct klist *), M_KQUEUE, M_WAITOK); FILEDESC_LOCK(fdp); - newsize = fdp->fd_knlistsize; - while (newsize <= kn->kn_id) - newsize += KQEXTENT; - if (newsize != size) { - FILEDESC_UNLOCK(fdp); - free(list, M_TEMP); - FILEDESC_LOCK(fdp); - goto retry; + /* force a reload from memory */ + fd_knlistsize = (volatile int)fdp->fd_knlistsize; + if (fd_knlistsize > kn->kn_id) { + FREE(list, M_TEMP); + goto bigenough; + } + if (fdp->fd_knlist != NULL) { + bcopy(fdp->fd_knlist, list, + fd_knlistsize * sizeof(struct klist *)); + FREE(fdp->fd_knlist, M_KQUEUE); } - bcopy(fdp->fd_knlist, list, - fdp->fd_knlistsize * sizeof(struct klist *)); - bzero((caddr_t)list + - fdp->fd_knlistsize * sizeof(struct klist *), - (size - fdp->fd_knlistsize) * sizeof(struct klist *)); - if (fdp->fd_knlist != NULL) - oldlist = fdp->fd_knlist; - else - oldlist = NULL; + bzero((caddr_t)list + fd_knlistsize * sizeof(struct klist *), + (size - fd_knlistsize) * sizeof(struct klist *)); fdp->fd_knlistsize = size; fdp->fd_knlist = list; - FILEDESC_UNLOCK(fdp); - if (oldlist != NULL) - FREE(oldlist, M_KQUEUE); - FILEDESC_LOCK(fdp); } +bigenough: list = &fdp->fd_knlist[kn->kn_id]; done: FILEDESC_UNLOCK(fdp);