76 (io_sendfile_f)NET_SYS_SENDFILE, |
76 (io_sendfile_f)NET_SYS_SENDFILE, |
77 (io_close_f)net_sys_close, |
77 (io_close_f)net_sys_close, |
78 NULL, |
78 NULL, |
79 (io_setmode_f)net_sys_setmode, |
79 (io_setmode_f)net_sys_setmode, |
80 (io_poll_f)net_sys_poll, |
80 (io_poll_f)net_sys_poll, |
|
81 0, |
81 0 |
82 0 |
82 }; |
83 }; |
83 |
84 |
84 IOStream http_io_funcs = { |
85 IOStream http_io_funcs = { |
85 (io_write_f)net_http_write, |
86 (io_write_f)net_http_write, |
88 (io_sendfile_f)net_http_sendfile, |
89 (io_sendfile_f)net_http_sendfile, |
89 (io_close_f)net_http_close, |
90 (io_close_f)net_http_close, |
90 (io_finish_f)net_http_finish, |
91 (io_finish_f)net_http_finish, |
91 (io_setmode_f)net_http_setmode, |
92 (io_setmode_f)net_http_setmode, |
92 (io_poll_f)net_http_poll, |
93 (io_poll_f)net_http_poll, |
93 0 |
94 0, |
|
95 IO_STREAM_TYPE_HTTP |
94 }; |
96 }; |
95 |
97 |
96 IOStream ssl_io_funcs = { |
98 IOStream ssl_io_funcs = { |
97 (io_write_f)net_ssl_write, |
99 (io_write_f)net_ssl_write, |
98 (io_writev_f)net_ssl_writev, |
100 (io_writev_f)net_ssl_writev, |
100 NULL, |
102 NULL, |
101 (io_close_f)net_ssl_close, |
103 (io_close_f)net_ssl_close, |
102 (io_finish_f)net_ssl_finish, |
104 (io_finish_f)net_ssl_finish, |
103 (io_setmode_f)net_ssl_setmode, |
105 (io_setmode_f)net_ssl_setmode, |
104 (io_poll_f)net_ssl_poll, |
106 (io_poll_f)net_ssl_poll, |
105 0 |
107 0, |
|
108 IO_STREAM_TYPE_SSL |
106 }; |
109 }; |
107 |
110 |
|
111 static int net_write_max_attempts = 16384; |
|
112 |
|
113 void io_set_max_writes(int n) { |
|
114 net_write_max_attempts = 1; |
|
115 } |
108 |
116 |
109 /* |
117 /* |
110 * Sysstream implementation |
118 * Sysstream implementation |
111 */ |
119 */ |
112 |
120 |
298 http->read_eof = WS_FALSE; |
306 http->read_eof = WS_FALSE; |
299 return 0; |
307 return 0; |
300 } |
308 } |
301 |
309 |
302 int httpstream_enable_chunked_write(IOStream *st) { |
310 int httpstream_enable_chunked_write(IOStream *st) { |
303 if(st->write != (io_write_f)net_http_write) { |
311 if(st->type != IO_STREAM_TYPE_HTTP) { |
304 log_ereport(LOG_FAILURE, "%s", "httpstream_enable_chunked_write: IOStream is not an HttpStream"); |
312 log_ereport(LOG_FAILURE, "%s", "httpstream_enable_chunked_write: IOStream is not an HttpStream"); |
305 return 1; |
313 return 1; |
306 } |
314 } |
307 HttpStream *http = (HttpStream*)st; |
315 HttpStream *http = (HttpStream*)st; |
308 http->chunked_enc = WS_TRUE; |
316 http->chunked_enc = WS_TRUE; |
874 } |
882 } |
875 return r; |
883 return r; |
876 } |
884 } |
877 |
885 |
878 ssize_t net_write(SYS_NETFD fd, const void *buf, size_t nbytes) { |
886 ssize_t net_write(SYS_NETFD fd, const void *buf, size_t nbytes) { |
879 ssize_t r = ((IOStream*)fd)->write(fd, buf, nbytes); |
887 size_t w = 0; |
880 if(r < 0) { |
888 size_t remaining = nbytes; |
|
889 const char *cbuf = buf; |
|
890 ssize_t r = 0; |
|
891 int attempts = 0; |
|
892 while(w < nbytes && attempts < net_write_max_attempts) { |
|
893 r = ((IOStream*)fd)->write(fd, cbuf, remaining); |
|
894 if(r <= 0) { |
|
895 break; |
|
896 } |
|
897 w += r; |
|
898 cbuf += r; |
|
899 remaining -= r; |
|
900 attempts++; |
|
901 } |
|
902 if(r < 0 && w == 0) { |
881 return IO_ERROR; |
903 return IO_ERROR; |
882 } |
904 } |
883 return r; |
905 return w; |
884 } |
906 } |
885 |
907 |
886 ssize_t net_writev(SYS_NETFD fd, struct iovec *iovec, int iovcnt) { |
908 ssize_t net_writev(SYS_NETFD fd, struct iovec *iovec, int iovcnt) { |
887 ssize_t r = ((IOStream*)fd)->writev(fd, iovec, iovcnt); |
909 ssize_t r = ((IOStream*)fd)->writev(fd, iovec, iovcnt); |
888 if(r < 0) { |
910 if(r < 0) { |