aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/mhd_send.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-08-01 20:44:41 +0200
committerChristian Grothoff <christian@grothoff.org>2019-08-01 20:44:41 +0200
commitc5081fb276b52fc9d48b9ba441686727eafaaad8 (patch)
treed8741e84111ed226c2bc2426e18d4e90bbd85184 /src/microhttpd/mhd_send.c
parentda7cb682a24915a4bc37faf2c76583996fe26aea (diff)
downloadlibmicrohttpd-c5081fb276b52fc9d48b9ba441686727eafaaad8.tar.gz
libmicrohttpd-c5081fb276b52fc9d48b9ba441686727eafaaad8.zip
always set nodelay, except if we cannot cork
Diffstat (limited to 'src/microhttpd/mhd_send.c')
-rw-r--r--src/microhttpd/mhd_send.c166
1 files changed, 62 insertions, 104 deletions
diff --git a/src/microhttpd/mhd_send.c b/src/microhttpd/mhd_send.c
index 7ca2b506..9b07115c 100644
--- a/src/microhttpd/mhd_send.c
+++ b/src/microhttpd/mhd_send.c
@@ -49,7 +49,8 @@ pre_cork_setsockopt (struct MHD_Connection *connection,
49 bool want_cork) 49 bool want_cork)
50{ 50{
51#if HAVE_MSG_MORE 51#if HAVE_MSG_MORE
52#else 52 /* We use the MSG_MORE option for corking, no need for extra syscalls! */
53#elif defined(MHD_TCP_CORK_NOPUSH)
53 int ret; 54 int ret;
54 55
55 /* If sk_cork_on is already what we pass in, return. */ 56 /* If sk_cork_on is already what we pass in, return. */
@@ -58,84 +59,38 @@ pre_cork_setsockopt (struct MHD_Connection *connection,
58 /* nothing to do, success! */ 59 /* nothing to do, success! */
59 return; 60 return;
60 } 61 }
61 62 if (! want_cork)
62 ret = -1; 63 return; /* nothing to do *pre* syscall! */
63#if TCP_CORK 64 ret = MHD_socket_cork_ (connection->socket_fd,
64 if (want_cork) 65 true);
65 {
66 const MHD_SCKT_OPT_BOOL_ on_val = 1;
67
68 ret = setsockopt (connection->socket_fd,
69 IPPROTO_TCP,
70 TCP_CORK,
71 (const void *) &on_val,
72 sizeof (on_val));
73 }
74#elif TCP_NOPUSH
75 if (want_cork)
76 {
77 const MHD_SCKT_OPT_BOOL_ on_val = 1;
78 /* TCP_NOPUSH has the same logic as MSG_MSG_MORE.
79 * The two are more or less equivalent by a source
80 * transformation (ie
81 * send(MSG_MORE) => "set TCP_NOPUSH + send() + clear TCP_NOPUSH".
82 * Both of them are really fairly "local", but TCP_NOPUSH has a
83 * _notion_ of persistency that is entirely lacking in MSG_MORE.
84 * ... with TCP_NOPUSH you basically have to know what your last
85 * write is, and clear the bit _before_ that write if you want
86 * to avoid bad latencies.
87 * https://yarchive.net/comp/linux/sendfile.html A thread from 2001,
88 * take with 18 grains of salt. */
89
90 ret = setsockopt (connection->socket_fd,
91 IPPROTO_TCP,
92 TCP_NOPUSH,
93 (const void *) &on_val,
94 sizeof (on_val));
95 }
96#elif TCP_NODELAY
97 {
98 const MHD_SCKT_OPT_BOOL_ off_val = 0;
99 const MHD_SCKT_OPT_BOOL_ on_val = 1;
100
101 ret = setsockopt (connection->socket_fd,
102 IPPROTO_TCP,
103 TCP_NODELAY,
104 (const void *) want_cork ? &off_val : &on_val,
105 sizeof (on_val));
106 }
107#endif
108 if (0 == ret) 66 if (0 == ret)
109 { 67 {
110 connection->sk_cork_on = want_cork; 68 connection->sk_cork_on = true;
69 return;
111 } 70 }
112 else 71 switch (errno)
113 { 72 {
114 switch (errno) 73 case ENOTSOCK:
115 { 74 /* FIXME: Could be we are talking to a pipe, maybe remember this
116 case ENOTSOCK: 75 and avoid all setsockopt() in the future? */
117 /* FIXME: Could be we are talking to a pipe, maybe remember this 76 break;
118 and avoid all setsockopt() in the future? */ 77 case EBADF:
119 break; 78 /* FIXME: should we die hard here? */
120 case EBADF: 79 break;
121 /* FIXME: should we die hard here? */ 80 case EINVAL:
122 break; 81 /* FIXME: optlen invalid, should at least log this, maybe die */
123 case EINVAL: 82 break;
124 /* FIXME: optlen invalid, should at least log this, maybe die */ 83 case EFAULT:
125 break; 84 /* FIXME: wopsie, should at leats log this, maybe die */
126 case EFAULT: 85 break;
127 /* FIXME: wopsie, should at leats log this, maybe die */ 86 case ENOPROTOOPT:
128 break; 87 /* FIXME: optlen unknown, should at least log this */
129 case ENOPROTOOPT: 88 break;
130 /* FIXME: optlen unknown, should at least log this */ 89 default:
131 break; 90 /* any others? man page does not list more... */
132 default: 91 break;
133 /* any others? man page does not list more... */
134 break;
135 }
136 } 92 }
137 return; 93#endif
138#endif /* MSG_MORE */
139} 94}
140 95
141 96
@@ -150,7 +105,8 @@ post_cork_setsockopt (struct MHD_Connection *connection,
150 bool want_cork) 105 bool want_cork)
151{ 106{
152#if HAVE_MSG_MORE 107#if HAVE_MSG_MORE
153#else 108 /* We use the MSG_MORE option for corking, no need for extra syscalls! */
109#elif defined(MHD_TCP_CORK_NOPUSH)
154 int ret; 110 int ret;
155 111
156 /* If sk_cork_on is already what we pass in, return. */ 112 /* If sk_cork_on is already what we pass in, return. */
@@ -159,38 +115,40 @@ post_cork_setsockopt (struct MHD_Connection *connection,
159 /* nothing to do, success! */ 115 /* nothing to do, success! */
160 return; 116 return;
161 } 117 }
162 ret = -1; 118 if (want_cork)
163#if TCP_CORK 119 return; /* nothing to do *post* syscall (in fact, we should never
164 if (! want_cork) 120 get here, as sk_cork_on should have succeeded in the
165 { 121 pre-syscall) */
166 const MHD_SCKT_OPT_BOOL_ off_val = 0; 122 ret = MHD_socket_cork_ (connection->socket_fd,
167 123 false);
168 ret = setsockopt (connection->socket_fd,
169 IPPROTO_TCP,
170 TCP_CORK,
171 &off_val,
172 sizeof (off_val));
173 }
174#elif TCP_NOPUSH
175 if (! want_cork)
176 {
177 const MHD_SCKT_OPT_BOOL_ off_val = 0;
178
179 ret = setsockopt (connection->socket_fd,
180 IPPROTO_TCP,
181 TCP_NOPUSH,
182 (const void *) &off_val,
183 sizeof (off_val));
184 }
185#elif TCP_NODELAY
186 /* nothing to do */
187#endif
188 if (0 == ret) 124 if (0 == ret)
189 { 125 {
190 connection->sk_cork_on = want_cork; 126 connection->sk_cork_on = false;
127 return;
128 }
129 switch (errno)
130 {
131 case ENOTSOCK:
132 /* FIXME: Could be we are talking to a pipe, maybe remember this
133 and avoid all setsockopt() in the future? */
134 break;
135 case EBADF:
136 /* FIXME: should we die hard here? */
137 break;
138 case EINVAL:
139 /* FIXME: optlen invalid, should at least log this, maybe die */
140 break;
141 case EFAULT:
142 /* FIXME: wopsie, should at leats log this, maybe die */
143 break;
144 case ENOPROTOOPT:
145 /* FIXME: optlen unknown, should at least log this */
146 break;
147 default:
148 /* any others? man page does not list more... */
149 break;
191 } 150 }
192 return; 151#endif
193#endif /* MSG_MORE */
194} 152}
195 153
196 154