diff -N -u -r -X exclude_files squid-1.0.beta15/src/comm.c squid-1.0.beta15.henrik/src/comm.c --- squid-1.0.beta15/src/comm.c Mon Jun 10 03:20:39 1996 +++ squid-1.0.beta15.henrik/src/comm.c Mon Jun 10 20:19:37 1996 @@ -460,6 +460,7 @@ int fd; { FD_ENTRY *conn = NULL; + struct close_handler *close_handler; if (fd < 0) return -1; @@ -477,8 +478,13 @@ debug(5, 5, "comm_close: FD %d\n", fd); /* update fdstat */ fdstat_close(fd); - if (conn->close_handler) - conn->close_handler(fd, conn->close_data); + /* Call close handlers */ + for(close_handler=conn->close_handler;close_handler;close_handler=conn->close_handler) { + debug(5, 7, "comm_close: calling handler %p\n",close_handler->handler); + conn->close_handler=close_handler->next; + close_handler->handler(fd, close_handler->data); + safe_free(close_handler); + } memset(conn, '\0', sizeof(FD_ENTRY)); return close(fd); } @@ -818,10 +824,6 @@ fd_table[fd].lifetime_handler = handler; fd_table[fd].lifetime_data = client_data; } - if (type & COMM_SELECT_CLOSE) { - fd_table[fd].close_handler = handler; - fd_table[fd].close_data = client_data; - } } int comm_get_select_handler(fd, type, handler_ptr, client_data_ptr) @@ -853,6 +855,42 @@ return 0; /* XXX What is meaningful? */ } +void comm_add_close_handler(fd, handler, data) + int fd; + int (*handler)(); + void *data; +{ + struct close_handler *new=xmalloc(sizeof(*new)); + + debug(5,5,"comm_add_close_handler: fd=%d handler=0x%p data=0x%p\n",fd,handler,data); + + new->handler=handler; + new->data=data; + new->next=fd_table[fd].close_handler; + fd_table[fd].close_handler=new; +} + +void comm_remove_close_handler(fd, handler, data) + int fd; + int (*handler)(); + void *data; +{ + struct close_handler *p, *last=NULL; + + /* Find handler in list */ + for(p=fd_table[fd].close_handler;p!=NULL;last=p,p=p->next) + if (p->handler == handler && p->data == data) + break; /* This is our handler */ + if(!p) + fatal_dump("comm_remove_close_handler: Handler not found!\n"); + + /* Remove list entry */ + if(last) + last->next=p->next; + else + fd_table[fd].close_handler=p->next; + safe_free(p); +} static int commSetNoLinger(fd) int fd; @@ -979,6 +1017,7 @@ fd_set except_x; int num; struct timeval tv; + struct close_handler *close_handler, *next; FD_ENTRY *f = NULL; debug(5, 0, "examine_select: Examining open file descriptors...\n"); @@ -995,15 +1034,22 @@ if (num < 0) { f = &fd_table[fd]; debug(5, 0, "WARNING: FD %d has handlers, but it's invalid.\n", fd); - debug(5, 0, "lifetm:%p tmout:%p read:%p write:%p expt:%p\n", + debug(5, 0, "lifetm:%p tmout:%p read:%p write:%p expt:%p", f->lifetime_handler, f->timeout_handler, f->read_handler, f->write_handler, f->except_handler); + for (close_handler = f->close_handler;close_handler;close_handler=close_handler->next) + debug(5,0," close:%p",close_handler->handler); + debug(5,0,"\n"); if (f->close_handler) { - debug(5, 0, "examine_select: Calling Close Handler\n"); - f->close_handler(fd, f->close_data); + for(close_handler=f->close_handler;close_handler;close_handler=close_handler->next) { + next=close_handler->next; + debug(5, 0, "examine_select: Calling Close Handler %p\n",close_handler->handler); + close_handler->handler(fd, close_handler->data); + safe_free(close_handler); + } } else if (f->lifetime_handler) { debug(5, 0, "examine_select: Calling Lifetime Handler\n"); f->lifetime_handler(fd, f->lifetime_data); diff -N -u -r -X exclude_files squid-1.0.beta15/src/comm.h squid-1.0.beta15.henrik/src/comm.h --- squid-1.0.beta15/src/comm.h Tue Jun 4 18:09:41 1996 +++ squid-1.0.beta15.henrik/src/comm.h Mon Jun 10 20:16:47 1996 @@ -21,7 +21,6 @@ #define COMM_SELECT_EXCEPT (0x4) #define COMM_SELECT_TIMEOUT (0x8) #define COMM_SELECT_LIFETIME (0x10) -#define COMM_SELECT_CLOSE (0x20) typedef int (*PF) _PARAMS((int, void *)); @@ -30,6 +29,12 @@ #define FD_ASCII_NOTE_SZ 64 +struct close_handler { + PF handler; + void *data; + struct close_handler *next; +}; + typedef struct fde { int openned; /* Set if we did a comm_connect. Ignored for ftp_pipes. */ int sender; /* Set if this fd is connected to a client */ @@ -40,20 +45,19 @@ /* Select handlers. */ void *client_data; /* App. data to associate w/ handled conn. */ - int (*read_handler) (); /* Read select handler. */ + PF read_handler; /* Read select handler. */ void *read_data; /* App. data to associate w/ handled conn. */ - int (*write_handler) (); /* Write select handler. */ + PF write_handler; /* Write select handler. */ void *write_data; /* App. data to associate w/ handled conn. */ - int (*except_handler) (); /* Except select handler. */ + PF except_handler; /* Except select handler. */ void *except_data; /* App. data to associate w/ handled conn. */ - int (*timeout_handler) (); /* Timeout handler. */ + PF timeout_handler; /* Timeout handler. */ time_t timeout_time; /* Allow 1-second granularity timeouts */ time_t timeout_delta; /* The delta requested */ void *timeout_data; /* App. data to associate w/ handled conn. */ - int (*lifetime_handler) (); /* Lifetime expire handler. */ + PF lifetime_handler; /* Lifetime expire handler. */ void *lifetime_data; /* App. data to associate w/ handled conn. */ - int (*close_handler) (); - void *close_data; + struct close_handler *close_handler; /* Linked list of close handlers */ char ascii_note[FD_ASCII_NOTE_SZ]; unsigned int comm_type; time_t stall_until; /* don't select for read until this time reached */ @@ -82,6 +86,8 @@ extern int comm_set_fd_lifetime _PARAMS((int fd, int lifetime)); extern void comm_set_select_handler _PARAMS((int fd, unsigned int type, PF, void *)); extern void comm_set_select_handler_plus_timeout _PARAMS((int, unsigned int, PF, void *, time_t)); +extern void comm_add_close_handler _PARAMS((int fd, PF, void *)); +extern void comm_remove_close_handler _PARAMS((int fd, PF, void *)); extern int comm_udp_recv _PARAMS((int, char *, int, struct sockaddr_in *, int *)); extern int comm_udp_send _PARAMS((int fd, char *host, u_short port, char *buf, int len)); extern int comm_udp_sendto _PARAMS((int fd, struct sockaddr_in *, int size, char *buf, int len)); diff -N -u -r -X exclude_files squid-1.0.beta15/src/ftp.c squid-1.0.beta15.henrik/src/ftp.c --- squid-1.0.beta15/src/ftp.c Mon Jun 10 15:06:11 1996 +++ squid-1.0.beta15.henrik/src/ftp.c Mon Jun 10 18:21:58 1996 @@ -552,8 +552,7 @@ /* Pipe/socket created ok */ /* register close handler */ - comm_set_select_handler(data->ftp_fd, - COMM_SELECT_CLOSE, + comm_add_close_handler(data->ftp_fd, (PF) ftpStateFree, (void *) data); diff -N -u -r -X exclude_files squid-1.0.beta15/src/gopher.c squid-1.0.beta15.henrik/src/gopher.c --- squid-1.0.beta15/src/gopher.c Mon Jun 10 03:20:43 1996 +++ squid-1.0.beta15.henrik/src/gopher.c Mon Jun 10 18:20:07 1996 @@ -869,8 +869,7 @@ gopherStateFree(-1, data); return COMM_ERROR; } - comm_set_select_handler(sock, - COMM_SELECT_CLOSE, + comm_add_close_handler(sock, (PF) gopherStateFree, (void *) data); diff -N -u -r -X exclude_files squid-1.0.beta15/src/http.c squid-1.0.beta15.henrik/src/http.c --- squid-1.0.beta15/src/http.c Mon Jun 10 15:55:55 1996 +++ squid-1.0.beta15.henrik/src/http.c Mon Jun 10 18:20:37 1996 @@ -573,8 +573,7 @@ request = get_free_request_t(); httpState->request = requestLink(request); /* register the handler to free HTTP state data when the FD closes */ - comm_set_select_handler(sock, - COMM_SELECT_CLOSE, + comm_add_close_handler(sock, (PF) httpStateFree, (void *) httpState); @@ -644,8 +643,7 @@ storeLockObject(httpState->entry = entry, NULL, NULL); httpState->req_hdr = req_hdr; httpState->request = requestLink(request); - comm_set_select_handler(sock, - COMM_SELECT_CLOSE, + comm_add_close_handler(sock, (PF) httpStateFree, (void *) httpState); diff -N -u -r -X exclude_files squid-1.0.beta15/src/icp.c squid-1.0.beta15.henrik/src/icp.c --- squid-1.0.beta15/src/icp.c Mon Jun 10 03:20:44 1996 +++ squid-1.0.beta15.henrik/src/icp.c Mon Jun 10 18:17:02 1996 @@ -1544,8 +1544,7 @@ COMM_SELECT_LIFETIME, (PF) asciiConnLifetimeHandle, (void *) icpState); - comm_set_select_handler(fd, - COMM_SELECT_CLOSE, + comm_add_close_handler(fd, (PF) icpStateFree, (void *) icpState); comm_read(fd, diff -N -u -r -X exclude_files squid-1.0.beta15/src/ipcache.c squid-1.0.beta15.henrik/src/ipcache.c --- squid-1.0.beta15/src/ipcache.c Mon Jun 10 15:05:52 1996 +++ squid-1.0.beta15.henrik/src/ipcache.c Mon Jun 10 20:31:53 1996 @@ -18,6 +18,7 @@ int fd; IPH handler; void *handlerData; + ipcache_entry *i; struct _ip_pending *next; }; @@ -88,6 +89,8 @@ static ipcache_entry *ipcache_get _PARAMS((char *)); static int dummy_handler _PARAMS((int, struct hostent * hp, void *)); static int ipcacheExpiredEntry _PARAMS((ipcache_entry *)); +static void ipcache_close_pending _PARAMS((int fd, void *data)); +int ipcache_nbgethostbyname _PARAMS((char *name, int fd, IPH handler, void *handlerData)); #ifdef UNUSED_CODE static int ipcache_hash_entry_count _PARAMS((void)); #endif @@ -455,6 +458,7 @@ i->pending_head = p->next; if (p->handler) { nhandler++; + comm_remove_close_handler(p->fd, (PF) ipcache_close_pending, (void *) p); p->handler(p->fd, (i->status == IP_CACHED) ? &(i->entry) : NULL, p->handlerData); @@ -772,6 +776,43 @@ return 0; } +static void ipcache_close_pending(fd, data) + int fd; + void *data; +{ + struct _ip_pending *pending = (struct _ip_pending *) data; + + debug(14, 0, "ipcache_close_pending: host=%s fd=%d handler=%p\n", + pending->i->name, fd, pending->handler); + + pending->fd = -1; + pending->handler = NULL; + pending->handlerData = NULL; + pending->i = NULL; +} + +static void ipcache_add_pending(i, fd, handler, handlerData) + ipcache_entry *i; + int fd; + IPH handler; + void *handlerData; +{ + struct _ip_pending *pending = xcalloc(1, sizeof(struct _ip_pending)); + struct _ip_pending **I = NULL; + + pending->fd = fd; + pending->handler = handler; + pending->handlerData = handlerData; + pending->i = i; + + for (I = &(i->pending_head); *I; I = &((*I)->next)); + *I = pending; + + comm_add_close_handler(fd, + (PF) ipcache_close_pending, + (void *) pending); +} + int ipcache_nbgethostbyname(name, fd, handler, handlerData) char *name; int fd; @@ -779,8 +820,6 @@ void *handlerData; { ipcache_entry *i = NULL; - struct _ip_pending *pending = NULL; - struct _ip_pending **I = NULL; dnsserver_t *dnsData = NULL; if (!handler) @@ -804,14 +843,10 @@ /* MISS: No entry, create the new one */ debug(14, 5, "ipcache_nbgethostbyname: MISS for '%s'\n", name); IpcacheStats.misses++; - pending = xcalloc(1, sizeof(struct _ip_pending)); - pending->fd = fd; - pending->handler = handler; - pending->handlerData = handlerData; i = ipcache_create(); i->name = xstrdup(name); i->status = IP_PENDING; - i->pending_head = pending; + ipcache_add_pending(i, fd, handler, handlerData); ipcache_add_to_hash(i); } else if (i->status == IP_CACHED || i->status == IP_NEGATIVE_CACHED) { /* HIT */ @@ -820,23 +855,13 @@ IpcacheStats.negative_hits++; else IpcacheStats.hits++; - pending = xcalloc(1, sizeof(struct _ip_pending)); - pending->fd = fd; - pending->handler = handler; - pending->handlerData = handlerData; - for (I = &(i->pending_head); *I; I = &((*I)->next)); - *I = pending; + ipcache_add_pending(i, fd, handler, handlerData); ipcache_call_pending(i); return 0; } else if (i->status == IP_PENDING) { debug(14, 4, "ipcache_nbgethostbyname: PENDING for '%s'\n", name); IpcacheStats.pending_hits++; - pending = xcalloc(1, sizeof(struct _ip_pending)); - pending->fd = fd; - pending->handler = handler; - pending->handlerData = handlerData; - for (I = &(i->pending_head); *I; I = &((*I)->next)); - *I = pending; + ipcache_add_pending(i, fd, handler, handlerData); return 0; } else { fatal_dump("ipcache_nbgethostbyname: BAD ipcache_entry status"); @@ -1042,8 +1067,9 @@ /* look for matched fd */ for (p = i->pending_head; p; p = p->next) { if (p->fd == fd) { + comm_remove_close_handler(p->fd, (PF) ipcache_close_pending, (void *) p); p->handler = NULL; - safe_free(p->handlerData); + p->fd = -1; /* let ipcache_call_pending() remove from the linked list */ return 1; } diff -N -u -r -X exclude_files squid-1.0.beta15/src/ssl.c squid-1.0.beta15.henrik/src/ssl.c --- squid-1.0.beta15/src/ssl.c Sat Jun 8 00:30:28 1996 +++ squid-1.0.beta15.henrik/src/ssl.c Mon Jun 10 18:17:23 1996 @@ -400,8 +400,7 @@ sslState->server.fd = sock; sslState->server.buf = xmalloc(SQUID_TCP_SO_RCVBUF); sslState->client.buf = xmalloc(SQUID_TCP_SO_RCVBUF); - comm_set_select_handler(sslState->server.fd, - COMM_SELECT_CLOSE, + comm_add_close_handler(sslState->server.fd, (PF) sslStateFree, (void *) sslState); ipcache_nbgethostbyname(request->host, diff -N -u -r -X exclude_files squid-1.0.beta15/src/store.c squid-1.0.beta15.henrik/src/store.c --- squid-1.0.beta15/src/store.c Mon Jun 10 16:02:32 1996 +++ squid-1.0.beta15.henrik/src/store.c Mon Jun 10 19:48:01 1996 @@ -1464,7 +1464,7 @@ STORE_REBUILDING_FAST : STORE_REBUILDING_SLOW; } /* Remove timestamp in case we crashe during rebuild */ - safeunlink(tmp_filename, 0); + safeunlink(tmp_filename, 1); /* close the existing write-only swaplog, and open a temporary * write-only swaplog */ if (file_write_unlock(swaplog_fd, swaplog_lock) != DISK_OK) diff -N -u -r -X exclude_files squid-1.0.beta15/src/wais.c squid-1.0.beta15.henrik/src/wais.c --- squid-1.0.beta15/src/wais.c Fri Jun 7 00:29:51 1996 +++ squid-1.0.beta15.henrik/src/wais.c Mon Jun 10 18:18:02 1996 @@ -258,8 +258,7 @@ data->relayport = getWaisRelayPort(); data->mime_hdr = mime_hdr; strncpy(data->request, url, MAX_URL); - comm_set_select_handler(sock, - COMM_SELECT_CLOSE, + comm_add_close_handler(sock, (PF) waisStateFree, (void *) data);