Date: Mon, 26 Aug 2002 23:58:51 +0100 From: Dominic Marks <dominic_marks@btinternet.com> To: freebsd-hackers@freebsd.org Subject: Re: kevent and pipes interaction on 4.6-STABLE Message-ID: <20020826225851.GA93947@gallium> In-Reply-To: <20020826222647.GC92538@gallium> References: <20020826221727.GB92538@gallium> <20020826222647.GC92538@gallium>
next in thread | previous in thread | raw e-mail | index | archive | help
--HcAYCG3uE/tztfnV Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hey, The best time to find and fix problems in code is just after you've submitted it to a public forum. It is also the worst time. :-) 1. Removed pointless traversal on kevent structures in Job_CatchOutput which I was doing before. Now all kevent objects store the address of their assigned job in the udata field. 2. Fixed one instance where some variables which should be hiden behind USE_SELECT preprocessor had snuck out. Updated diff attached, the main problem persists. Thanks, -- Dominic Marks Computer & Politics Geek [work]::[npl.co.uk] << dominic.marks at npl.co.uk >> [educ]::[umist.ac.uk] << notyet-known at umist.ac.uk >> [home]::[btinternet] << dominic_marks at btinternet.com >> --HcAYCG3uE/tztfnV Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="make-kqueue.diff" Index: job.c =================================================================== RCS file: /media/cvs/freebsd/src/usr.bin/make/job.c,v retrieving revision 1.38 diff -u -r1.38 job.c --- job.c 20 Jun 2002 19:28:00 -0000 1.38 +++ job.c 26 Aug 2002 22:44:05 -0000 @@ -1,4 +1,5 @@ /* + * Copyright (c) 2002, Dominic Marks * Copyright (c) 1988, 1989, 1990, 1993 * The Regents of the University of California. All rights reserved. * Copyright (c) 1988, 1989 by Adam de Boor @@ -105,6 +106,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/file.h> +#include <sys/event.h> #include <sys/time.h> #include <sys/wait.h> #include <err.h> @@ -237,8 +239,13 @@ * (2) a job can only be run locally, but * nLocal equals maxLocal */ #ifndef RMT_WILL_WATCH -static fd_set outputs; /* Set of descriptors of pipes connected to +#ifdef USE_SELECT +static fd_set outputs; + /* Set of descriptors of pipes connected to * the output channels of children */ +#else +static int kq = -1; +#endif /* USE_SELECT */ #endif STATIC GNode *lastNode; /* The node for which output was most recently @@ -704,11 +711,29 @@ JobClose(job) Job *job; { +#ifndef USE_SELECT + int rv; + struct kevent ke; +#endif /* ! USE_SELECT */ + if (usePipes) { #ifdef RMT_WILL_WATCH - Rmt_Ignore(job->inPipe); + + Rmt_Ignore(job->inPipe); #else +#ifdef USE_SELECT FD_CLR(job->inPipe, &outputs); +#else + memset(&ke, 0, sizeof(struct kevent)); + printf("xxx: closing job on fd %d\n", job->inPipe); + ke.ident = job->inPipe; + ke.filter = EVFILT_READ; + ke.flags = EV_DELETE; + rv = kevent(kq, &ke, 1, NULL, 0, NULL); + if (rv < 0) { + Punt("kevent(2) failed when closing a job"); + } +#endif /* USE_SELECT */ #endif if (job->outPipe != job->inPipe) { (void) close(job->outPipe); @@ -1192,6 +1217,10 @@ Job *job; /* Job to execute */ char **argv; { +#ifndef USE_SELECT + int rv; + struct kevent ke; +#endif /* USE_SELECT */ int cpid; /* ID of new child */ if (DEBUG(JOB)) { @@ -1305,7 +1334,20 @@ #ifdef RMT_WILL_WATCH Rmt_Watch(job->inPipe, JobLocalInput, job); #else +#ifdef USE_SELECT FD_SET(job->inPipe, &outputs); +#else + memset(&ke, 0, sizeof(struct kevent)); + printf("xxx: new job on fd %d\n", job->inPipe); + ke.ident = job->inPipe; + ke.filter = EVFILT_READ; + ke.flags = EV_ADD; + ke.udata = (void *) job; + rv = kevent(kq, &ke, 1, NULL, 0, NULL); + if (rv < 0) { + Punt("kevent(2) failed when adding a job"); + } +#endif /* USE_SELECT */ #endif /* RMT_WILL_WATCH */ } @@ -2313,16 +2355,24 @@ void Job_CatchOutput() { - int nfds; - struct timeval timeout; - fd_set readfds; +#ifdef USE_SELECT + int nfds; + struct timeval timeout; + fd_set readfds; +#else +#define KEVENT_SET_SIZE 8 + int kq, rv, idx; + Job *kjob; + struct kevent ke[KEVENT_SET_SIZE]; +#endif /* USE_SELECT */ LstNode ln; Job *job; #ifdef RMT_WILL_WATCH int pnJobs; /* Previous nJobs */ #endif - + (void) fflush(stdout); + #ifdef RMT_WILL_WATCH pnJobs = nJobs; @@ -2347,26 +2397,46 @@ } #else if (usePipes) { +#ifdef USE_SELECT readfds = outputs; - timeout.tv_sec = SEL_SEC; - timeout.tv_usec = SEL_USEC; - if ((nfds = select(FD_SETSIZE, &readfds, (fd_set *) 0, - (fd_set *) 0, &timeout)) <= 0) - return; + timeout.tv_sec = SEL_SEC; + timeout.tv_usec = SEL_USEC; + + if ((nfds = select(FD_SETSIZE, &readfds, (fd_set *) 0, + (fd_set *) 0, &timeout)) <= 0) { + return; + } else { + if (Lst_Open(jobs) == FAILURE) { + Punt("Cannot open job table"); + } + while (nfds && (ln = Lst_Next(jobs)) != NULL) { + job = (Job *) Lst_Datum(ln); + if (FD_ISSET(job->inPipe, &readfds)) { + JobDoOutput(job, FALSE); + nfds -= 1; + } + } + } +#else + memset(&ke, 0, sizeof(struct kevent) * KEVENT_SET_SIZE); + rv = kevent(kq, NULL, 0, ke, KEVENT_SET_SIZE, NULL); + if (rv <= 0) { + return; + } else { - if (Lst_Open(jobs) == FAILURE) { - Punt("Cannot open job table"); - } - while (nfds && (ln = Lst_Next(jobs)) != NULL) { - job = (Job *) Lst_Datum(ln); - if (FD_ISSET(job->inPipe, &readfds)) { - JobDoOutput(job, FALSE); - nfds -= 1; + if (Lst_Open(jobs) == FAILURE) { + Punt("Cannot open job table"); } - } - Lst_Close(jobs); + for (idx = 0; idx < rv; idx++) { + kjob = (Job *) ke[idx].udata; + /* we found the kevent for the job */ + JobDoOutput(kjob, FALSE); + continue; + } + Lst_Close(jobs); } +#endif /* USE_SELECT */ } #endif /* RMT_WILL_WATCH */ } @@ -2439,6 +2509,16 @@ } else { targFmt = TARG_FMT; } + +#ifndef USE_SELECT + if (kq < 0) { + kq = kqueue(); + printf("xxx: kq = %d\n", kq); + } + if (kq < 0) { + Punt("kqueue(2) could not assign a kqueue"); + } +#endif /* ! USE_SELECT */ if (shellPath == NULL) { /* --HcAYCG3uE/tztfnV-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020826225851.GA93947>