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 1652
 			fd=c->fd;
1651 1653
 			do_close_fd=0; /* don't close the fd on exit, it's in use */
1652 1654
 #ifdef TCP_FD_CACHE
1653
-		}else if (likely(tcp_options.fd_cache && 
1655
+			use_fd_cache=0; /* don't cache: problems would arise due to the
1656
+							   close() on cache eviction (if the fd is still 
1657
+							   used). If it has to be cached then dup() _must_ 
1658
+							   be used */
1659
+		}else if (likely(use_fd_cache && 
1654 1660
 							((fd_cache_e=tcp_fd_cache_get(c))!=0))){
1655 1661
 			fd=fd_cache_e->fd;
1656 1662
 			do_close_fd=0;
... ...
@@ -1797,7 +1803,7 @@ error:
1797 1803
 #endif /* TCP_BUF_WRITE */
1798 1804
 end:
1799 1805
 #ifdef TCP_FD_CACHE
1800
-	if (unlikely((fd_cache_e==0) && tcp_options.fd_cache)){
1806
+	if (unlikely((fd_cache_e==0) && use_fd_cache)){
1801 1807
 		tcp_fd_cache_add(c, fd);
1802 1808
 	}else
1803 1809
 #endif /* TCP_FD_CACHE */
... ...
@@ -1815,8 +1821,6 @@ conn_wait_error:
1815 1821
 	 * tcp_main receives a CONN_ERROR it*/
1816 1822
 	c->state=S_CONN_BAD;
1817 1823
 	TCPCONN_LOCK;
1818
-		/* FIXME: race: what if CONN_ERROR is sent by another tcp_send() to
1819
-		 * tcp_main ? */
1820 1824
 		if (c->flags & F_CONN_HASHED){
1821 1825
 			/* if some other parallel tcp_send did send CONN_ERROR to
1822 1826
 			 * 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 701
 	}
699 702
 	/* if conn->state is ERROR or BAD => force timeout too */
700 703
 	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);
704
+		LOG(L_ERR, "ERROR: tcpconn_read_timeout: io_watch_del failed for %p"
705
+					" id %d fd %d, state %d, flags %x, main fd %d\n",
706
+					c, c->id, c->fd, c->state, c->flags, c->s);
703 707
 	}
704 708
 	tcpconn_listrm(tcp_conn_lst, c, c_next, c_prev);
705 709
 	release_tcpconn(c, (c->state<0)?CONN_ERROR:CONN_RELEASE, tcpmain_sock);
... ...
@@ -791,10 +795,12 @@ again:
791 795
 			local_timer_reinit(&con->timer);
792 796
 			local_timer_add(&tcp_reader_ltimer, &con->timer,
793 797
 								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);
798
+			if (unlikely(io_watch_add(&io_w, s, POLLIN, F_TCPCONN, con)<0)){
799
+				LOG(L_CRIT, "ERROR: tcpconn_receive: handle_io: io_watch_add "
800
+							"failed for %p id %d fd %d, state %d, flags %x,"
801
+							" main fd %d, refcnt %d\n",
802
+							con, con->id, con->fd, con->state, con->flags,
803
+							con->s, atomic_get(&con->refcnt));
798 804
 				tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev);
799 805
 				local_timer_del(&tcp_reader_ltimer, &con->timer);
800 806
 				goto con_error;
... ...
@@ -815,13 +821,16 @@ read_error:
815 821
 				ret=-1; /* some error occured */
816 822
 				if (unlikely(io_watch_del(&io_w, con->fd, idx,
817 823
 											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);
824
+					LOG(L_CRIT, "ERROR: tcpconn_receive: handle_io: "
825
+							"io_watch_del failed for %p id %d fd %d,"
826
+							" state %d, flags %x, main fd %d, refcnt %d\n",
827
+							con, con->id, con->fd, con->state,
828
+							con->flags, con->s, atomic_get(&con->refcnt));
821 829
 				}
822 830
 				tcpconn_listrm(tcp_conn_lst, con, c_next, c_prev);
823 831
 				local_timer_del(&tcp_reader_ltimer, &con->timer);
824
-				con->state=S_CONN_BAD;
832
+				if (unlikely(resp!=CONN_EOF))
833
+					con->state=S_CONN_BAD;
825 834
 				release_tcpconn(con, resp, tcpmain_sock);
826 835
 			}else{
827 836
 				/* update timeout */