...
|
...
|
@@ -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");
|