--------------------- PatchSet 7057 Date: 2005/09/27 08:10:16 Author: adri Branch: tidyup_deferred_reads Tag: (none) Log: Begin implementing a comm_read() to complement comm_write(). its not tested yet and we may not need it in my planned tidyup but just in case.. Members: src/comm.c:1.18.6.5.6.2->1.18.6.5.6.3 src/structs.h:1.48.2.34.4.2->1.48.2.34.4.3 src/typedefs.h:1.25.6.6.12.1->1.25.6.6.12.2 Index: squid/src/comm.c =================================================================== RCS file: /cvsroot/squid-sf//squid/src/comm.c,v retrieving revision 1.18.6.5.6.2 retrieving revision 1.18.6.5.6.3 diff -u -r1.18.6.5.6.2 -r1.18.6.5.6.3 --- squid/src/comm.c 27 Sep 2005 06:32:20 -0000 1.18.6.5.6.2 +++ squid/src/comm.c 27 Sep 2005 08:10:16 -0000 1.18.6.5.6.3 @@ -1,6 +1,6 @@ /* - * $Id: comm.c,v 1.18.6.5.6.2 2005/09/27 06:32:20 adri Exp $ + * $Id: comm.c,v 1.18.6.5.6.3 2005/09/27 08:10:16 adri Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -962,6 +962,90 @@ comm_write(fd, mb.buf, mb.size, handler, handler_data, memBufFreeFunc(&mb)); } +static void +commReadStateCallbackAndFree(int fd, int code) +{ + CommReadStateData state = fd_table[fd].read_state; + CWCB *callback = state.handler; + void *data = state.handler_data; + size_t readlen = state.readlen; + void *buf = state.buf; + + if (callback == NULL) + return; + + fd_table[fd].read_state.handler = NULL; + + if (callback && cbdataValid(data)) + callback(fd, buf, readlen, code, data); + cbdataUnlock(data); +} + +void +commHandleRead(int fd, void *data) +{ + CommReadStateData *state = data; + int len = 0; + + debug(5, 5) ("commHandleRead: FD %d:\n", fd); + + len = FD_READ_METHOD(fd, state->buf, state->size); + debug(5, 5) ("commHandleRead: read() returns %d\n", len); + statCounter.syscalls.sock.reads++; + fd_table[fd].read_state.readlen = len; + if (len > 0) { + fd_bytes(fd, len, FD_READ); + /* XXX delay pools? */ + kb_incr(&statCounter.server.all.kbytes_in, len); + commReadStateCallbackAndFree(fd, COMM_OK); + return; + } else if (len < 0) { + debug(5, ignoreErrno(errno) ? 3: 1) + ("commHandleRead: FD %d: read failure: %s\n", fd, xstrerror()); + if (! ignoreErrno(errno)) { + commReadStateCallbackAndFree(fd, COMM_ERROR); + comm_close(fd); + return; + } + } else if (len == 0) { + commReadStateCallbackAndFree(fd, COMM_ERR_CLOSING); + comm_close(fd); + return; + } + assert(1==0); /* XXX shouldn't ever get here */ +} + + +/* + * Schedule a read + * + * + This shouldn't be done on a closing FD + * + The comm handler will be called when the FD is ready, regardless + * of error condition or not. The handler should check that + * the result was COMM_OK and if not prepare to have the FD closed. + * comm_close() will be called after the handler completes in the + * case of an error. + */ +void +comm_read(int fd, char *buf, int size, CRCB *handler, void *handler_data) +{ + CommReadStateData *state = &fd_table[fd].read_state; + + /* make sure we're not reading anything and not closing */ + assert(fd_table[fd].flags.open == 1); + assert(! fd_table[fd].flags.closing); + assert(fd_table[fd].read_state.handler == NULL); + + debug (5, 4) ("comm_read: queueing read for FD %d\n", fd); + + state->buf = (char *) buf; + state->size = size; + state->handler = handler; + state->handler_data = handler_data; + cbdataLock(handler_data); + commSetSelect(fd, COMM_SELECT_READ, commHandleRead, state, 0); +} + /* * hm, this might be too general-purpose for all the places we'd Index: squid/src/structs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/structs.h,v retrieving revision 1.48.2.34.4.2 retrieving revision 1.48.2.34.4.3 diff -u -r1.48.2.34.4.2 -r1.48.2.34.4.3 --- squid/src/structs.h 27 Sep 2005 06:32:21 -0000 1.48.2.34.4.2 +++ squid/src/structs.h 27 Sep 2005 08:10:16 -0000 1.48.2.34.4.3 @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.48.2.34.4.2 2005/09/27 06:32:21 adri Exp $ + * $Id: structs.h,v 1.48.2.34.4.3 2005/09/27 08:10:16 adri Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -772,6 +772,15 @@ FREE *free_func; }; +struct _CommReadStateData { + char *buf; + size_t size; + size_t readlen; + int flags; + CRCB *handler; + void *handler_data; +}; + struct _fde { unsigned int type; u_short local_port; @@ -816,6 +825,7 @@ DEFER *defer_check; /* check if we should defer read */ void *defer_data; CommWriteStateData rwstate; /* State data for comm_write */ + CommReadStateData read_state; /* State data for comm_read */ READ_HANDLER *read_method; WRITE_HANDLER *write_method; #if USE_SSL Index: squid/src/typedefs.h =================================================================== RCS file: /cvsroot/squid-sf//squid/src/typedefs.h,v retrieving revision 1.25.6.6.12.1 retrieving revision 1.25.6.6.12.2 diff -u -r1.25.6.6.12.1 -r1.25.6.6.12.2 --- squid/src/typedefs.h 27 Sep 2005 04:57:14 -0000 1.25.6.6.12.1 +++ squid/src/typedefs.h 27 Sep 2005 08:10:16 -0000 1.25.6.6.12.2 @@ -1,6 +1,6 @@ /* - * $Id: typedefs.h,v 1.25.6.6.12.1 2005/09/27 04:57:14 adri Exp $ + * $Id: typedefs.h,v 1.25.6.6.12.2 2005/09/27 08:10:16 adri Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -173,6 +173,7 @@ typedef struct _cachemgr_passwd cachemgr_passwd; typedef struct _refresh_t refresh_t; typedef struct _CommWriteStateData CommWriteStateData; +typedef struct _CommReadStateData CommReadStateData; typedef struct _ErrorState ErrorState; typedef struct _dlink_node dlink_node; typedef struct _dlink_list dlink_list; @@ -229,6 +230,7 @@ #endif typedef void CWCB(int fd, char *, size_t size, int flag, void *data); +typedef void CRCB(int fd, char *, size_t retlen, int flag, void *data); typedef void CNCB(int fd, int status, void *); typedef void FREE(void *);