Browse code

- fix: tcp fd cache: don't cache own fd in a tcp_reader - various cleanups/better error messages

Andrei Pelinescu-Onciul authored on 22/12/2007 08:11:14
Showing 2 changed files
... ...
@@ -1448,7 +1448,9 @@ int tcp_send(struct dest_info* dst, union sockaddr_union* from,
1448 1448
 #endif /* TCP_BUF_WRITE */
1449 1449
 #ifdef TCP_FD_CACHE
1450 1450
 	struct fd_cache_entry* fd_cache_e;
1451
+	int use_fd_cache;
1451 1452
 	
1453
+	use_fd_cache=tcp_options.fd_cache;
1452 1454
 	fd_cache_e=0;
1453 1455
 #endif /* TCP_FD_CACHE */
1454 1456
 	do_close_fd=1; /* close the fd on exit */
... ...
@@ -1650,7 +1652,11 @@ get_fd:
1650 1650
 			fd=c->fd;
1651 1651
 			do_close_fd=0; /* don't close the fd on exit, it's in use */
1652 1652
 #ifdef TCP_FD_CACHE
1653
-		}else if (likely(tcp_options.fd_cache && 
1653
+			use_fd_cache=0; /* don't cache: problems would arise due to the
1654
+							   close() on cache eviction (if the fd is still 
1655
+							   used). If it has to be cached then dup() _must_ 
1656
+							   be used */
1657
+		}else if (likely(use_fd_cache && 
1654 1658
 							((fd_cache_e=tcp_fd_cache_get(c))!=0))){
1655 1659
 			fd=fd_cache_e->fd;
1656 1660
 			do_close_fd=0;
... ...
@@ -1797,7 +1803,7 @@ error:
1797 1797
 #endif /* TCP_BUF_WRITE */
1798 1798
 end:
1799 1799
 #ifdef TCP_FD_CACHE
1800
-	if (unlikely((fd_cache_e==0) && tcp_options.fd_cache)){
1800
+	if (unlikely((fd_cache_e==0) && use_fd_cache)){
1801 1801
 		tcp_fd_cache_add(c, fd);
1802 1802
 	}else
1803 1803
 #endif /* TCP_FD_CACHE */
... ...
@@ -1815,8 +1821,6 @@ conn_wait_error:
1815 1815
 	 * tcp_main receives a CONN_ERROR it*/
1816 1816
 	c->state=S_CONN_BAD;
1817 1817
 	TCPCONN_LOCK;
1818
-		/* FIXME: race: what if CONN_ERROR is sent by another tcp_send() to
1819
-		 * tcp_main ? */
1820 1818
 		if (c->flags & F_CONN_HASHED){
1821 1819
 			/* if some other parallel tcp_send did send CONN_ERROR to
1822 1820
 			 * tcp_main, the connection might be already detached */
... ...
@@ -674,7 +674,10 @@ void release_tcpconn(struct tcp_connection* c, long state, int unix_sock)
674 674
 		DBG(" extra_data %p\n", c->extra_data);
675 675
 		/* release req & signal the parent */
676 676
 		c->reader_pid=0; /* reset it */
677
-		if (c->fd!=-1) close(c->fd);
677
+		if (c->fd!=-1){
678
+			close(c->fd);
679
+			c->fd=-1;
680
+		}
678 681
 		/* errno==EINTR, EWOULDBLOCK a.s.o todo */
679 682
 		response[0]=(long)c;
680 683
 		response[1]=state;
... ...
@@ -698,8 +701,9 @@ static ticks_t tcpconn_read_timeout(ticks_t t, struct timer_ln* tl, void* data)
698 698
 	}
699 699
 	/* if conn->state is ERROR or BAD => force timeout too */
700 700
 	if (unlikely(io_watch_del(&io_w, c->fd, -1, IO_FD_CLOSING)<0)){
701
-		LOG(L_ERR, "ERROR; tcpconn_read_timeout: io_watch_del failed for %p"
702
-					" id %d fd %d, state %d\n", c, c->id, c->fd, c->state);
701
+		LOG(L_ERR, "ERROR: tcpconn_read_timeout: io_watch_del failed for %p"
702
+					" id %d fd %d, state %d, flags %x, main fd %d\n",
703
+					c, c->id, c->fd, c->state, c->flags, c->s);
703 704
 	}
704 705
 	tcpconn_listrm(tcp_conn_lst, c, c_next, c_prev);
705 706
 	release_tcpconn(c, (c->state<0)?CONN_ERROR:CONN_RELEASE, tcpmain_sock);
... ...
@@ -791,10 +795,12 @@ again:
791 791
 			local_timer_reinit(&con->timer);
792 792
 			local_timer_add(&tcp_reader_ltimer, &con->timer,
793 793
 								S_TO_TICKS(TCP_CHILD_TIMEOUT), t);
794
-			if (unlikely(io_watch_add(&io_w, s, POLLIN, F_TCPCONN, con))<0){
795
-				LOG(L_CRIT, "ERROR; tcpconn_receive: handle_io: io_watch_add "
796
-							"failed for %p id %d fd %d, state %d\n",
797
-							con, con->id, con->fd, con->state);
794
+			if (unlikely(io_watch_add(&io_w, s, POLLIN, F_TCPCONN, con)<0)){
795
+				LOG(L_CRIT, "ERROR: tcpconn_receive: handle_io: io_watch_add "
796
+							"failed for %p id %d fd %d, state %d, flags %x,"
797
+							" main fd %d, refcnt %d\n",
798
+							con, con->id, con->fd, con->state, con->flags,
799
+							con->s, atomic_get(&con->refcnt));
798 800
 				tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev);
799 801
 				local_timer_del(&tcp_reader_ltimer, &con->timer);
800 802
 				goto con_error;
... ...
@@ -815,13 +821,16 @@ read_error:
815 815
 				ret=-1; /* some error occured */
816 816
 				if (unlikely(io_watch_del(&io_w, con->fd, idx,
817 817
 											IO_FD_CLOSING) < 0)){
818
-				LOG(L_CRIT, "ERROR; tcpconn_receive: handle_io: io_watch_del "
819
-							"failed for %p id %d fd %d, state %d\n",
820
-							con, con->id, con->fd, con->state);
818
+					LOG(L_CRIT, "ERROR: tcpconn_receive: handle_io: "
819
+							"io_watch_del failed for %p id %d fd %d,"
820
+							" state %d, flags %x, main fd %d, refcnt %d\n",
821
+							con, con->id, con->fd, con->state,
822
+							con->flags, con->s, atomic_get(&con->refcnt));
821 823
 				}
822 824
 				tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev);
823 825
 				local_timer_del(&tcp_reader_ltimer, &con->timer);
824
-				con->state=S_CONN_BAD;
826
+				if (unlikely(resp!=CONN_EOF))
827
+					con->state=S_CONN_BAD;
825 828
 				release_tcpconn(con, resp, tcpmain_sock);
826 829
 			}else{
827 830
 				/* update timeout */