mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-28 15:28:30 +00:00
Make send() block in non-blocking mode
This commit is contained in:
parent
3c58ecd00c
commit
774c67fcd3
2 changed files with 20 additions and 1 deletions
|
@ -54,7 +54,14 @@ textwindows ssize_t sys_send_nt(int fd, const struct iovec *iov, size_t iovlen,
|
||||||
ssize_t rc;
|
ssize_t rc;
|
||||||
struct Fd *f = g_fds.p + fd;
|
struct Fd *f = g_fds.p + fd;
|
||||||
sigset_t m = __sig_block();
|
sigset_t m = __sig_block();
|
||||||
bool nonblock = (f->flags & O_NONBLOCK) || (flags & _MSG_DONTWAIT);
|
|
||||||
|
// we don't check O_NONBLOCK because we want to avoid needing to call
|
||||||
|
// WSAPoll() every time we write() to a non-blocking socket. WIN32 is
|
||||||
|
// unsafe at canceling socket sends. lots of code doesn't check write
|
||||||
|
// return status. good programs that sincerely want to avoid blocking
|
||||||
|
// on send() operations should have already called poll() beforehand.
|
||||||
|
bool nonblock = flags & _MSG_DONTWAIT;
|
||||||
|
|
||||||
flags &= ~_MSG_DONTWAIT;
|
flags &= ~_MSG_DONTWAIT;
|
||||||
rc = __winsock_block(f->handle, flags, -nonblock, f->sndtimeo, m,
|
rc = __winsock_block(f->handle, flags, -nonblock, f->sndtimeo, m,
|
||||||
sys_send_nt_start, &(struct SendArgs){iov, iovlen});
|
sys_send_nt_start, &(struct SendArgs){iov, iovlen});
|
||||||
|
|
|
@ -30,6 +30,18 @@
|
||||||
/**
|
/**
|
||||||
* Sends data to network socket.
|
* Sends data to network socket.
|
||||||
*
|
*
|
||||||
|
* Calling `send(fd, p, n, 0)` is equivalent to `write(fd, p, n)`.
|
||||||
|
*
|
||||||
|
* On Windows, calling send() or write() on a socket in `O_NONBLOCK`
|
||||||
|
* mode will block. This is done for many reasons. First, most UNIX OSes
|
||||||
|
* have a similar behavior, due to how little code checks the return
|
||||||
|
* status of write(). Secondly, WIN32 has bugs that prevent us from
|
||||||
|
* canceling an overlapped WSASend() operation safely. Programs that
|
||||||
|
* want to avoid send() blocking should call poll() beforehand with the
|
||||||
|
* POLLOUT flag to test when the socket can safely be written without
|
||||||
|
* blocking. It's also possible to pass `MSG_DONTWAIT` via `flags` in
|
||||||
|
* which case send() will do this for you automatically.
|
||||||
|
*
|
||||||
* @param fd is the file descriptor returned by socket()
|
* @param fd is the file descriptor returned by socket()
|
||||||
* @param buf is the data to send, which we'll copy if necessary
|
* @param buf is the data to send, which we'll copy if necessary
|
||||||
* @param size is the byte-length of buf
|
* @param size is the byte-length of buf
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue