Browse code

- tcp: more flags (no fixes, preparations for next set of changes)

Andrei Pelinescu-Onciul authored on 21/05/2008 10:16:46
Showing 2 changed files
... ...
@@ -79,6 +79,8 @@
79 79
 #define F_CONN_FORCE_EOF  512 /* act as if an EOF was received */
80 80
 #define F_CONN_OOB_DATA  1024 /* out of band data on the connection */
81 81
 #define F_CONN_WR_ERROR  2048 /* write error on the fd */
82
+#define F_CONN_WANTS_RD  4096  /* conn. should be watched for READ */
83
+#define F_CONN_WANTS_WR  8192  /* conn. should be watched for WRITE */
82 84
 
83 85
 
84 86
 enum tcp_req_errors {	TCP_REQ_INIT, TCP_REQ_OK, TCP_READ_ERROR,
... ...
@@ -169,6 +169,14 @@
169 169
 #include <fcntl.h> /* must be included after io_wait.h if SIGIO_RT is used */
170 170
 
171 171
 
172
+#ifdef NO_MSG_DONTWAIT
173
+#ifndef MSG_DONTWAIT
174
+/* should work inside tcp_main */
175
+#define MSG_DONTWAIT 0
176
+#endif
177
+#endif /*NO_MSG_DONTWAIT */
178
+
179
+
172 180
 #define TCP_PASS_NEW_CONNECTION_ON_DATA /* don't pass a new connection
173 181
 										   immediately to a child, wait for
174 182
 										   some data on it first */
... ...
@@ -2555,7 +2563,7 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
2555 2563
 			local_timer_reinit(&tcpconn->timer);
2556 2564
 			local_timer_add(&tcp_main_ltimer, &tcpconn->timer, crt_timeout, t);
2557 2565
 			/* must be after the de-ref*/
2558
-			tcpconn->flags|=(F_CONN_MAIN_TIMER|F_CONN_READ_W);
2566
+			tcpconn->flags|=(F_CONN_MAIN_TIMER|F_CONN_READ_W|F_CONN_WANTS_RD);
2559 2567
 			tcpconn->flags&=~(F_CONN_READER|F_CONN_OOB_DATA);
2560 2568
 #ifdef TCP_BUF_WRITE
2561 2569
 			if (unlikely(tcpconn->flags & F_CONN_WRITE_W))
... ...
@@ -2745,14 +2753,22 @@ inline static int handle_ser_child(struct process_table* p, int fd_i)
2745 2753
 			 * no need for reinit */
2746 2754
 			local_timer_add(&tcp_main_ltimer, &tcpconn->timer, 
2747 2755
 								tcp_con_lifetime, t);
2748
-			tcpconn->flags|=(F_CONN_MAIN_TIMER|F_CONN_READ_W);
2756
+			tcpconn->flags|=(F_CONN_MAIN_TIMER|F_CONN_READ_W|F_CONN_WANTS_RD)
2757
+#ifdef TCP_BUF_WRITE
2758
+					/* not used for now, the connection is sent to tcp_main
2759
+					 * before knowing whether we can write on it or we should 
2760
+					 * wait */
2761
+							| (((int)!(tcpconn->flags & F_CONN_WANTS_WR)-1)& 
2762
+								F_CONN_WRITE_W)
2763
+#endif /* TCP_BUF_WRITE */
2764
+				;
2749 2765
 			tcpconn->flags&=~F_CONN_FD_CLOSED;
2750 2766
 			flags=POLLIN 
2751 2767
 #ifdef TCP_BUF_WRITE
2752 2768
 					/* not used for now, the connection is sent to tcp_main
2753 2769
 					 * before knowing if we can write on it or we should 
2754 2770
 					 * wait */
2755
-					| (((int)!(tcpconn->flags & F_CONN_WRITE_W)-1) & POLLOUT)
2771
+					| (((int)!(tcpconn->flags & F_CONN_WANTS_WR)-1) & POLLOUT)
2756 2772
 #endif /* TCP_BUF_WRITE */
2757 2773
 					;
2758 2774
 			if (unlikely(
... ...
@@ -2775,7 +2791,8 @@ inline static int handle_ser_child(struct process_table* p, int fd_i)
2775 2791
 			if (unlikely((tcpconn->state==S_CONN_BAD) || 
2776 2792
 							!(tcpconn->flags & F_CONN_HASHED) ))
2777 2793
 				break;
2778
-			if (!(tcpconn->flags & F_CONN_WRITE_W)){
2794
+			if (!(tcpconn->flags & F_CONN_WANTS_WR)){
2795
+				tcpconn->flags|=F_CONN_WANTS_WR;
2779 2796
 				t=get_ticks_raw();
2780 2797
 				if (likely((tcpconn->flags & F_CONN_MAIN_TIMER) && 
2781 2798
 					(TICKS_LT(tcpconn->wbuf_q.wr_timeout, tcpconn->timeout)) &&
... ...
@@ -2790,28 +2807,31 @@ inline static int handle_ser_child(struct process_table* p, int fd_i)
2790 2807
 							"timeout adjusted to %d s\n", tcpconn, 
2791 2808
 							TICKS_TO_S(tcpconn->wbuf_q.wr_timeout-t));
2792 2809
 				}
2793
-				if (!(tcpconn->flags & F_CONN_READ_W)){
2794
-					if (unlikely(io_watch_add(&io_h, tcpconn->s, POLLOUT,
2810
+				if (!(tcpconn->flags & F_CONN_WRITE_W)){
2811
+					tcpconn->flags|=F_CONN_WRITE_W;
2812
+					if (!(tcpconn->flags & F_CONN_READ_W)){
2813
+						if (unlikely(io_watch_add(&io_h, tcpconn->s, POLLOUT,
2795 2814
 												F_TCPCONN, tcpconn)<0)){
2796
-						LOG(L_CRIT, "ERROR: tcp_main: handle_ser_child: failed"
2797
-								    " to enable write watch on socket\n");
2798
-						if (tcpconn_try_unhash(tcpconn))
2799
-							tcpconn_put_destroy(tcpconn);
2800
-						break;
2801
-					}
2802
-				}else{
2803
-					if (unlikely(io_watch_chg(&io_h, tcpconn->s,
2804
-												POLLIN|POLLOUT, -1)<0)){
2805
-						LOG(L_CRIT, "ERROR: tcp_main: handle_ser_child: failed"
2806
-								    " to change socket watch events\n");
2807
-						io_watch_del(&io_h, tcpconn->s, -1, IO_FD_CLOSING);
2808
-						tcpconn->flags&=~F_CONN_READ_W;
2809
-						if (tcpconn_try_unhash(tcpconn))
2810
-							tcpconn_put_destroy(tcpconn);
2811
-						break;
2815
+							LOG(L_CRIT, "ERROR: tcp_main: handle_ser_child:"
2816
+										" failed to enable write watch on"
2817
+										" socket\n");
2818
+							if (tcpconn_try_unhash(tcpconn))
2819
+								tcpconn_put_destroy(tcpconn);
2820
+							break;
2821
+						}
2822
+					}else{
2823
+						if (unlikely(io_watch_chg(&io_h, tcpconn->s,
2824
+													POLLIN|POLLOUT, -1)<0)){
2825
+							LOG(L_CRIT, "ERROR: tcp_main: handle_ser_child:"
2826
+									" failed to change socket watch events\n");
2827
+							io_watch_del(&io_h, tcpconn->s, -1, IO_FD_CLOSING);
2828
+							tcpconn->flags&=~F_CONN_READ_W;
2829
+							if (tcpconn_try_unhash(tcpconn))
2830
+								tcpconn_put_destroy(tcpconn);
2831
+							break;
2832
+						}
2812 2833
 					}
2813 2834
 				}
2814
-				tcpconn->flags|=F_CONN_WRITE_W;
2815 2835
 			}else{
2816 2836
 				LOG(L_WARN, "tcp_main: hanlder_ser_child: connection %p"
2817 2837
 							" already watched for write\n", tcpconn);
... ...
@@ -2849,19 +2869,20 @@ inline static int handle_ser_child(struct process_table* p, int fd_i)
2849 2869
 			 * no need for reinit */
2850 2870
 			local_timer_add(&tcp_main_ltimer, &tcpconn->timer, 
2851 2871
 								tcp_con_lifetime, t);
2852
-			tcpconn->flags|=F_CONN_MAIN_TIMER|F_CONN_READ_W;
2872
+			tcpconn->flags|=F_CONN_MAIN_TIMER|F_CONN_READ_W|F_CONN_WANTS_RD;
2853 2873
 			if (unlikely(cmd==CONN_NEW_COMPLETE)){
2854 2874
 				/* check if needs to be watched for write */
2855 2875
 				lock_get(&tcpconn->write_lock);
2856 2876
 					/* if queue non empty watch it for write */
2857 2877
 					flags=(_wbufq_empty(tcpconn)-1)&POLLOUT;
2858 2878
 				lock_release(&tcpconn->write_lock);
2859
-				tcpconn->flags|=(!(flags&POLLOUT)-1)&F_CONN_WRITE_W;
2879
+				tcpconn->flags|=(!(flags&POLLOUT)-1)&
2880
+									(F_CONN_WRITE_W|F_CONN_WANTS_WR);
2860 2881
 			}else{
2861 2882
 				/* CONN_NEW_PENDING_WRITE */
2862 2883
 				/* no need to check, we have something queued for write */
2863 2884
 				flags=POLLOUT;
2864
-				tcpconn->flags|=F_CONN_WRITE_W;
2885
+				tcpconn->flags|=(F_CONN_WRITE_W|F_CONN_WANTS_WR);
2865 2886
 			}
2866 2887
 			flags|=POLLIN;
2867 2888
 			if (unlikely(
... ...
@@ -3027,7 +3048,7 @@ static inline int handle_new_connect(struct socket_info* si)
3027 3048
 		/* activate the timer */
3028 3049
 		local_timer_add(&tcp_main_ltimer, &tcpconn->timer, 
3029 3050
 								tcp_con_lifetime, get_ticks_raw());
3030
-		tcpconn->flags|=(F_CONN_MAIN_TIMER|F_CONN_READ_W);
3051
+		tcpconn->flags|=(F_CONN_MAIN_TIMER|F_CONN_READ_W|F_CONN_WANTS_RD);
3031 3052
 		if (unlikely(io_watch_add(&io_h, tcpconn->s, POLLIN, 
3032 3053
 													F_TCPCONN, tcpconn)<0)){
3033 3054
 			LOG(L_CRIT, "ERROR: tcp_main: handle_new_connect: failed to add"
... ...
@@ -3116,19 +3137,21 @@ inline static int handle_tcpconn_ev(struct tcp_connection* tcpconn, short ev,
3116 3137
 				 * there's really any data in the read buffer or the POLLIN
3117 3138
 				 * was generated by the error or EOF => to avoid loosing
3118 3139
 				 *  data it's safer to either directly check the read buffer 
3119
-				 *  or *  try a read)*/
3140
+				 *  or try a read)*/
3120 3141
 				/* in most cases the read buffer will be empty, so in general
3121 3142
 				 * is cheaper to check it here and then send the 
3122 3143
 				 * conn.  to a a child only if needed (another syscall + at 
3123 3144
 				 * least 2 * syscalls in the reader + ...) */
3124 3145
 				if ((ioctl(tcpconn->s, FIONREAD, &bytes)>=0) && (bytes>0)){
3125
-					tcpconn->flags&=~(F_CONN_WRITE_W|F_CONN_READ_W);
3146
+					tcpconn->flags&=~(F_CONN_WRITE_W|F_CONN_READ_W|
3147
+										F_CONN_WANTS_RD|F_CONN_WANTS_WR);
3126 3148
 					tcpconn->flags|=F_CONN_FORCE_EOF|F_CONN_WR_ERROR;
3127 3149
 					goto send_to_child;
3128 3150
 				}
3129 3151
 				/* if bytes==0 or ioctl failed, destroy the connection now */
3130 3152
 			}
3131
-			tcpconn->flags&=~(F_CONN_WRITE_W|F_CONN_READ_W);
3153
+			tcpconn->flags&=~(F_CONN_WRITE_W|F_CONN_READ_W|
3154
+								F_CONN_WANTS_RD|F_CONN_WANTS_WR);
3132 3155
 			if (unlikely(!tcpconn_try_unhash(tcpconn))){
3133 3156
 				LOG(L_CRIT, "BUG: tcpconn_ev: unhashed connection %p\n",
3134 3157
 							tcpconn);
... ...
@@ -3137,6 +3160,7 @@ inline static int handle_tcpconn_ev(struct tcp_connection* tcpconn, short ev,
3137 3160
 			goto error;
3138 3161
 		}
3139 3162
 		if (empty_q){
3163
+			tcpconn->flags&=~F_CONN_WANTS_WR;
3140 3164
 			if (!(tcpconn->flags & F_CONN_READ_W)){
3141 3165
 				if (unlikely(io_watch_del(&io_h, tcpconn->s, fd_i, 0)==-1)){
3142 3166
 					LOG(L_ERR, "ERROR: handle_tcpconn_ev: io_watch_del(2)"
... ...
@@ -3192,7 +3216,7 @@ send_to_child:
3192 3216
 		tcpconn->flags|= ((int)!(ev & POLLPRI) -1)  & F_CONN_OOB_DATA;
3193 3217
 		tcpconn->flags|=F_CONN_READER;
3194 3218
 		local_timer_del(&tcp_main_ltimer, &tcpconn->timer);
3195
-		tcpconn->flags&=~(F_CONN_MAIN_TIMER|F_CONN_READ_W);
3219
+		tcpconn->flags&=~(F_CONN_MAIN_TIMER|F_CONN_READ_W|F_CONN_WANTS_RD);
3196 3220
 		tcpconn_ref(tcpconn); /* refcnt ++ */
3197 3221
 		if (unlikely(send2child(tcpconn)<0)){
3198 3222
 			LOG(L_ERR,"ERROR: handle_tcpconn_ev: no children available\n");