--------------------- PatchSet 5201 Date: 2002/10/03 07:29:21 Author: adri Branch: commloops Tag: (none) Log: * move comm_accept() to comm_old_accept() * split up the iocallback stuff to handle multiple callback definitions - read/write may be able to sure IOCB, but accept() requires a little more attention * start writing the callback-driven accept() framework. It won't be very pretty (only one accept()ed socket per run through the loop) but it'll do for the initial refactoring. Members: src/client_side.c:1.52.4.3->1.52.4.4 src/comm.c:1.21.4.9->1.21.4.10 src/ftp.c:1.20.10.3->1.20.10.4 src/protos.h:1.49.4.6->1.49.4.7 src/typedefs.h:1.25.22.4->1.25.22.5 Index: squid/src/client_side.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/client_side.c,v retrieving revision 1.52.4.3 retrieving revision 1.52.4.4 diff -u -r1.52.4.3 -r1.52.4.4 --- squid/src/client_side.c 3 Oct 2002 01:22:18 -0000 1.52.4.3 +++ squid/src/client_side.c 3 Oct 2002 07:29:21 -0000 1.52.4.4 @@ -1,6 +1,6 @@ /* - * $Id: client_side.c,v 1.52.4.3 2002/10/03 01:22:18 adri Exp $ + * $Id: client_side.c,v 1.52.4.4 2002/10/03 07:29:21 adri Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -1708,7 +1708,7 @@ while (max-- && !httpAcceptDefer(sock, NULL)) { memset(&peer, '\0', sizeof(struct sockaddr_in)); memset(&me, '\0', sizeof(struct sockaddr_in)); - if ((fd = comm_accept(sock, &peer, &me)) < 0) { + if ((fd = comm_old_accept(sock, &peer, &me)) < 0) { if (!ignoreErrno(errno)) debug(50, 1) ("httpAccept: FD %d: accept failure: %s\n", sock, xstrerror()); @@ -1805,7 +1805,7 @@ while (max-- && !httpAcceptDefer(sock, NULL)) { memset(&peer, '\0', sizeof(struct sockaddr_in)); memset(&me, '\0', sizeof(struct sockaddr_in)); - if ((fd = comm_accept(sock, &peer, &me)) < 0) { + if ((fd = comm_old_accept(sock, &peer, &me)) < 0) { if (!ignoreErrno(errno)) debug(50, 1) ("httpsAccept: FD %d: accept failure: %s\n", sock, xstrerror()); Index: squid/src/comm.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/comm.c,v retrieving revision 1.21.4.9 retrieving revision 1.21.4.10 diff -u -r1.21.4.9 -r1.21.4.10 --- squid/src/comm.c 3 Oct 2002 01:22:19 -0000 1.21.4.9 +++ squid/src/comm.c 3 Oct 2002 07:29:21 -0000 1.21.4.10 @@ -1,6 +1,6 @@ /* - * $Id: comm.c,v 1.21.4.9 2002/10/03 01:22:19 adri Exp $ + * $Id: comm.c,v 1.21.4.10 2002/10/03 07:29:21 adri Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -83,20 +83,39 @@ IOCB *handler; void *handler_data; } read; + struct { + struct sockaddr_in me; + struct sockaddr_in pn; + IOACB *handler; + void *handler_data; + } accept; }; typedef struct _fdc_t fdc_t; +typedef enum { + COMM_CB_READ = 1, + COMM_CB_WRITE, + COMM_CB_ACCEPT +} comm_callback_t; + struct _CommCallbackData { + comm_callback_t type; dlink_node fd_node; dlink_node h_node; int fd; + int newfd; /* for accept() */ char *buf; int retval; - IOCB *callback; + union { + IOCB *r_callback; + IOACB *a_callback; + } c; void *callback_data; comm_err_t errcode; int xerrno; int seqnum; + struct sockaddr_in me; + struct sockaddr_in pn; }; typedef struct _CommCallbackData CommCallbackData; @@ -127,7 +146,7 @@ * code block. */ static void -comm_addiocallback(int fd, IOCB *callback, char *buf, size_t retval, comm_err_t errcode, +comm_addreadcallback(int fd, IOCB *callback, char *buf, size_t retval, comm_err_t errcode, int xerrno, void *callback_data) { CommCallbackData *cio; @@ -142,10 +161,41 @@ cio->retval = retval; cio->xerrno = xerrno; cio->errcode = errcode; - cio->callback = callback; + cio->c.r_callback = callback; cio->callback_data = callback_data; cio->seqnum = CommCallbackSeqnum; cio->buf = buf; + cio->type = COMM_CB_READ; + + /* Add it to the end of the list */ + dlinkAddTail(cio, &(cio->h_node), &CommCallbackList); + + /* and add it to the end of the fd list */ + dlinkAddTail(cio, &(cio->fd_node), &(fdc_table[fd].CommCallbackList)); + +} + + +static void +comm_addacceptcallback(int fd, int newfd, IOACB *callback, struct sockaddr_in *pn, + struct sockaddr_in *me, comm_err_t errcode, int xerrno, void *callback_data) +{ + CommCallbackData *cio; + + assert(fdc_table[fd].active == 1); + + /* Allocate a new struct */ + cio = memPoolAlloc(comm_callback_pool); + + /* Throw our data into it */ + cio->fd = fd; + cio->xerrno = xerrno; + cio->errcode = errcode; + cio->c.a_callback = callback; + cio->callback_data = callback_data; + cio->seqnum = CommCallbackSeqnum; + cio->type = COMM_CB_ACCEPT; + cio->newfd = newfd; /* Add it to the end of the list */ dlinkAddTail(cio, &(cio->h_node), &CommCallbackList); @@ -156,6 +206,26 @@ } +static void +comm_call_io_callback(CommCallbackData *cio) +{ + switch(cio->type) { + case COMM_CB_READ: + cio->c.r_callback(cio->fd, cio->buf, cio->retval, cio->errcode, cio->xerrno, + cio->callback_data); + break; + case COMM_CB_WRITE: + fatal("write comm hasn't been implemented yet!"); + break; + case COMM_CB_ACCEPT: + break; + default: + fatal("unknown comm io callback type!"); + break; + }; +} + + /* * call the IO callbacks * @@ -188,8 +258,7 @@ dlinkDelete(&cio->h_node, &CommCallbackList); dlinkDelete(&cio->fd_node, &(fdc_table[cio->fd].CommCallbackList)); - cio->callback(cio->fd, cio->buf, cio->retval, cio->errcode, cio->xerrno, - cio->callback_data); + comm_call_io_callback(cio); memPoolFree(comm_callback_pool, cio); } } @@ -205,7 +274,7 @@ assert(Fc->read.handler != NULL); - comm_addiocallback(fd, Fc->read.handler, Fc->read.buf, retval, errcode, xerrno, + comm_addreadcallback(fd, Fc->read.handler, Fc->read.buf, retval, errcode, xerrno, Fc->read.handler_data); Fc->read.handler = NULL; Fc->read.handler_data = NULL; @@ -717,7 +786,7 @@ /* Wait for an incoming connection on FD. FD should be a socket returned * from comm_old_listen. */ int -comm_accept(int fd, struct sockaddr_in *pn, struct sockaddr_in *me) +comm_old_accept(int fd, struct sockaddr_in *pn, struct sockaddr_in *me) { int sock; struct sockaddr_in P; @@ -728,13 +797,13 @@ statCounter.syscalls.sock.accepts++; if ((sock = accept(fd, (struct sockaddr *) &P, &Slen)) < 0) { if (ignoreErrno(errno)) { - debug(50, 5) ("comm_accept: FD %d: %s\n", fd, xstrerror()); + debug(50, 5) ("comm_old_accept: FD %d: %s\n", fd, xstrerror()); return COMM_NOMESSAGE; } else if (ENFILE == errno || EMFILE == errno) { - debug(50, 3) ("comm_accept: FD %d: %s\n", fd, xstrerror()); + debug(50, 3) ("comm_old_accept: FD %d: %s\n", fd, xstrerror()); return COMM_ERROR; } else { - debug(50, 1) ("comm_accept: FD %d: %s\n", fd, xstrerror()); + debug(50, 1) ("comm_old_accept: FD %d: %s\n", fd, xstrerror()); return COMM_ERROR; } } @@ -871,9 +940,7 @@ dlinkDelete(&cio->h_node, &CommCallbackList); dlinkDelete(&cio->fd_node, &(fdc_table[cio->fd].CommCallbackList)); - cio->callback(cio->fd, cio->buf, cio->retval, COMM_ERR_CLOSING, cio->xerrno, - cio->callback_data); - + comm_call_io_callback(cio); memPoolFree(comm_callback_pool, cio); } @@ -1264,3 +1331,74 @@ return 0; return F->defer_check(fd, F->defer_data); } + + +/* + * New-style listen and accept routines + * + * Listen simply registers our interest in an FD for listening, + * and accept takes a callback to call when an FD has been + * accept()ed. + */ +int +comm_listen(int sock) +{ + return comm_old_listen(sock); +} + + +/* + * This callback is called whenever a filedescriptor is ready + * to dupe itself and fob off an accept()ed connection + */ +void +comm_accept_callback(int fd, void *data) +{ + int newfd; + fdc_t *Fc; + + assert(fdc_table[fd].active == 1); + + Fc = &(fdc_table[fd]); + + /* Accept a new connection */ + newfd = comm_old_accept(fd, &Fc->accept.pn, &Fc->accept.me); + + if (newfd < 0) { + /* Issues - check them */ + if (ignoreErrno(errno)) { + /* register interest again */ + commSetSelect(fd, COMM_SELECT_READ, comm_accept_callback, NULL, 0); + return; + } + /* Problem! */ + comm_addacceptcallback(fd, -1, Fc->accept.handler, &Fc->accept.pn, &Fc->accept.me, COMM_ERROR, errno, Fc->accept.handler_data); + Fc->accept.handler = NULL; + Fc->accept.handler_data = NULL; + return; + } + + /* setup our new filedescriptor in fd_table */ + /* and set it up in fdc_table */ + + /* queue a completed callback with the new FD */ + comm_addacceptcallback(fd, newfd, Fc->accept.handler, &Fc->accept.pn, &Fc->accept.me, COMM_OK, 0, Fc->accept.handler_data); + Fc->accept.handler = NULL; + Fc->accept.handler_data = NULL; + +} + + +/* + * Notes: + * + the current interface will queue _one_ accept per io loop. + * this isn't very optimal and should be revisited at a later date. + */ +void +comm_accept(int fd, IOACB *handler, void *handler_data) +{ + assert(fd_table[fd].open == 1); + assert(fdc_table[fd].active == 1); + + /* make sure we're not pending! */ +} Index: squid/src/ftp.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/ftp.c,v retrieving revision 1.20.10.3 retrieving revision 1.20.10.4 diff -u -r1.20.10.3 -r1.20.10.4 --- squid/src/ftp.c 3 Oct 2002 01:22:19 -0000 1.20.10.3 +++ squid/src/ftp.c 3 Oct 2002 07:29:21 -0000 1.20.10.4 @@ -1,6 +1,6 @@ /* - * $Id: ftp.c,v 1.20.10.3 2002/10/03 01:22:19 adri Exp $ + * $Id: ftp.c,v 1.20.10.4 2002/10/03 07:29:21 adri Exp $ * * DEBUG: section 9 File Transfer Protocol (FTP) * AUTHOR: Harvest Derived @@ -1902,7 +1902,7 @@ comm_close(ftpState->ctrl.fd); return; } - fd = comm_accept(fd, &my_peer, &me); + fd = comm_old_accept(fd, &my_peer, &me); if (Config.Ftp.sanitycheck) { char *ipaddr = inet_ntoa(my_peer.sin_addr); if (strcmp(fd_table[ftpState->ctrl.fd].ipaddr, ipaddr) != 0) { @@ -1917,7 +1917,7 @@ } } if (fd < 0) { - debug(9, 1) ("ftpHandleDataAccept: comm_accept(%d): %s", fd, xstrerror()); + debug(9, 1) ("ftpHandleDataAccept: comm_old_accept(%d): %s", fd, xstrerror()); /* XXX Need to set error message */ ftpFail(ftpState); return; Index: squid/src/protos.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/protos.h,v retrieving revision 1.49.4.6 retrieving revision 1.49.4.7 diff -u -r1.49.4.6 -r1.49.4.7 --- squid/src/protos.h 3 Oct 2002 01:22:19 -0000 1.49.4.6 +++ squid/src/protos.h 3 Oct 2002 07:29:21 -0000 1.49.4.7 @@ -1,6 +1,6 @@ /* - * $Id: protos.h,v 1.49.4.6 2002/10/03 01:22:19 adri Exp $ + * $Id: protos.h,v 1.49.4.7 2002/10/03 07:29:21 adri Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -159,7 +159,7 @@ extern int commSetNonBlocking(int fd); extern int commUnsetNonBlocking(int fd); extern void commSetCloseOnExec(int fd); -extern int comm_accept(int fd, struct sockaddr_in *, struct sockaddr_in *); +extern int comm_oldaccept(int fd, struct sockaddr_in *, struct sockaddr_in *); extern void comm_close(int fd); extern void comm_reset_close(int fd); #if LINGERING_CLOSE Index: squid/src/typedefs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/typedefs.h,v retrieving revision 1.25.22.4 retrieving revision 1.25.22.5 diff -u -r1.25.22.4 -r1.25.22.5 --- squid/src/typedefs.h 26 Sep 2002 06:08:08 -0000 1.25.22.4 +++ squid/src/typedefs.h 3 Oct 2002 07:29:21 -0000 1.25.22.5 @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.25.22.4 2002/09/26 06:08:08 adri Exp $ + * $Id: typedefs.h,v 1.25.22.5 2002/10/03 07:29:21 adri Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -201,6 +201,8 @@ typedef void CWCB(int fd, char *, size_t size, comm_err_t flag, void *data); typedef void CNCB(int fd, comm_err_t status, void *); typedef void IOCB(int fd, char *, size_t size, comm_err_t flag, int xerrno, void *data); +typedef void IOACB(int fd, int nfd, struct sockaddr_in *me, struct sockaddr_in *pn, + comm_err_t flag, int xerrno, void *data); typedef void FREE(void *); typedef void CBDUNL(void *);