Index: kern_event.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_event.c,v retrieving revision 1.47 diff -c -8 -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 *************** *** 378,395 **** TAILQ_INIT(&kq->kq_head); FILE_LOCK(fp); fp->f_flag = FREAD | FWRITE; fp->f_type = DTYPE_KQUEUE; fp->f_ops = &kqueueops; TAILQ_INIT(&kq->kq_head); fp->f_data = kq; FILE_UNLOCK(fp); - FILEDESC_LOCK(fdp); td->td_retval[0] = fd; if (fdp->fd_knlistsize < 0) fdp->fd_knlistsize = 0; /* this process has a kq */ FILEDESC_UNLOCK(fdp); kq->kq_fdp = fdp; done2: mtx_unlock(&Giant); return (error); } --- 378,395 ---- TAILQ_INIT(&kq->kq_head); FILE_LOCK(fp); fp->f_flag = FREAD | FWRITE; fp->f_type = DTYPE_KQUEUE; fp->f_ops = &kqueueops; TAILQ_INIT(&kq->kq_head); fp->f_data = kq; FILE_UNLOCK(fp); 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); kq->kq_fdp = fdp; done2: mtx_unlock(&Giant); return (error); } *************** *** 948,1022 **** list = &fdp->fd_knlist[fd]; FILEDESC_UNLOCK(fdp); knote_remove(td, list); } static void knote_attach(struct knote *kn, struct filedesc *fdp) { ! struct klist *list, *oldlist, *tmp_knhash; u_long tmp_knhashmask; ! int size, newsize; FILEDESC_LOCK(fdp); ! 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) { 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)]; goto done; } if (fdp->fd_knlistsize <= kn->kn_id) { - retry: size = fdp->fd_knlistsize; while (size <= kn->kn_id) size += KQEXTENT; FILEDESC_UNLOCK(fdp); 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; } ! 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; fdp->fd_knlistsize = size; fdp->fd_knlist = list; - FILEDESC_UNLOCK(fdp); - if (oldlist != NULL) - FREE(oldlist, M_KQUEUE); - FILEDESC_LOCK(fdp); } list = &fdp->fd_knlist[kn->kn_id]; done: FILEDESC_UNLOCK(fdp); SLIST_INSERT_HEAD(list, kn, kn_link); kn->kn_status = 0; } /* --- 948,1011 ---- list = &fdp->fd_knlist[fd]; FILEDESC_UNLOCK(fdp); knote_remove(td, list); } static void knote_attach(struct knote *kn, struct filedesc *fdp) { ! struct klist *list, *tmp_knhash; u_long tmp_knhashmask; ! int size, fd_knlistsize; FILEDESC_LOCK(fdp); ! 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 ((volatile u_long)fdp->fd_knhashmask == 0) { fdp->fd_knhash = tmp_knhash; fdp->fd_knhashmask = tmp_knhashmask; } else { free(tmp_knhash, M_KQUEUE); } } list = &fdp->fd_knhash[KN_HASH(kn->kn_id, fdp->fd_knhashmask)]; goto done; } if (fdp->fd_knlistsize <= kn->kn_id) { size = fdp->fd_knlistsize; while (size <= kn->kn_id) size += KQEXTENT; FILEDESC_UNLOCK(fdp); MALLOC(list, struct klist *, size * sizeof(struct klist *), M_KQUEUE, M_WAITOK); FILEDESC_LOCK(fdp); ! /* 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); } ! bzero((caddr_t)list + fd_knlistsize * sizeof(struct klist *), ! (size - fd_knlistsize) * sizeof(struct klist *)); fdp->fd_knlistsize = size; fdp->fd_knlist = list; } + bigenough: list = &fdp->fd_knlist[kn->kn_id]; done: FILEDESC_UNLOCK(fdp); SLIST_INSERT_HEAD(list, kn, kn_link); kn->kn_status = 0; } /*