diff options
author | Xavier Leroy <xavier.leroy@inria.fr> | 2015-11-30 11:42:16 +0100 |
---|---|---|
committer | Xavier Leroy <xavier.leroy@inria.fr> | 2015-11-30 11:42:16 +0100 |
commit | 15ac614a894d2eb9414f68b449d7f153f5882f94 (patch) | |
tree | 66db7279536e6293e5dbec1b72dedf22ee26ebad /byterun/io.c | |
parent | 35dc44a00f1beed49c0affecfd38dbd313a24113 (diff) | |
download | ocaml-15ac614a894d2eb9414f68b449d7f153f5882f94.tar.gz |
Experiment: Win32 sockets in non-synchronous mode.
This is an attempt to address PR#4466, #5325, #6771. Not tested yet.
Diffstat (limited to 'byterun/io.c')
-rw-r--r-- | byterun/io.c | 64 |
1 files changed, 30 insertions, 34 deletions
diff --git a/byterun/io.c b/byterun/io.c index 60504f5862..48c9c00542 100644 --- a/byterun/io.c +++ b/byterun/io.c @@ -33,6 +33,7 @@ #include "caml/memory.h" #include "caml/misc.h" #include "caml/mlvalues.h" +#include "caml/osdeps.h" #include "caml/signals.h" #include "caml/sys.h" @@ -158,25 +159,12 @@ CAMLexport int caml_channel_binary_mode(struct channel *channel) #define EWOULDBLOCK (-1) #endif -static int do_write(int fd, char *p, int n) +static int do_write(int fd, int flags, char *p, int n) { int retcode; - -again: caml_enter_blocking_section(); - retcode = write(fd, p, n); + retcode = caml_write_fd(fd, flags & CHANNEL_FLAG_FROM_SOCKET, p, n); caml_leave_blocking_section(); - if (retcode == -1) { - if (errno == EINTR) goto again; - if ((errno == EAGAIN || errno == EWOULDBLOCK) && n > 1) { - /* We couldn't do a partial write here, probably because - n <= PIPE_BUF and POSIX says that writes of less than - PIPE_BUF characters must be atomic. - We first try again with a partial write of 1 character. - If that fails too, we'll raise Sys_blocked_io below. */ - n = 1; goto again; - } - } if (retcode == -1) caml_sys_io_error(NO_ARG); CAMLassert (retcode > 0); return retcode; @@ -194,7 +182,7 @@ CAMLexport int caml_flush_partial(struct channel *channel) towrite = channel->curr - channel->buff; CAMLassert (towrite >= 0); if (towrite > 0) { - written = do_write(channel->fd, channel->buff, towrite); + written = do_write(channel->fd, channel->flags, channel->buff, towrite); channel->offset += written; if (written < towrite) memmove(channel->buff, channel->buff + written, towrite - written); @@ -238,7 +226,7 @@ CAMLexport int caml_putblock(struct channel *channel, char *p, intnat len) fits to buffer and write the buffer */ memmove(channel->curr, p, free); towrite = channel->end - channel->buff; - written = do_write(channel->fd, channel->buff, towrite); + written = do_write(channel->fd, channel->flags, channel->buff, towrite); if (written < towrite) memmove(channel->buff, channel->buff + written, towrite - written); channel->offset += written; @@ -277,30 +265,28 @@ CAMLexport file_offset caml_pos_out(struct channel *channel) /* Input */ -/* caml_do_read is exported for Cash */ -CAMLexport int caml_do_read(int fd, char *p, unsigned int n) +static int do_read(int fd, int flags, char *p, unsigned int n) { int retcode; - do { - caml_enter_blocking_section(); - retcode = read(fd, p, n); -#if defined(_WIN32) - if (retcode == -1 && errno == ENOMEM && n > 16384){ - retcode = read(fd, p, 16384); - } -#endif - caml_leave_blocking_section(); - } while (retcode == -1 && errno == EINTR); + caml_enter_blocking_section(); + retcode = caml_read_fd(fd, flags & CHANNEL_FLAG_FROM_SOCKET, p, n); if (retcode == -1) caml_sys_io_error(NO_ARG); return retcode; } +/* caml_do_read is exported for Cash */ +CAMLexport int caml_do_read(int fd, char *p, unsigned int n) +{ + return do_read(fd, 0, p, n); +} + CAMLexport unsigned char caml_refill(struct channel *channel) { int n; - n = caml_do_read(channel->fd, channel->buff, channel->end - channel->buff); + n = do_read(channel->fd, channel->flags, + channel->buff, channel->end - channel->buff); if (n == 0) caml_raise_end_of_file(); channel->offset += n; channel->max = channel->buff + n; @@ -337,8 +323,8 @@ CAMLexport int caml_getblock(struct channel *channel, char *p, intnat len) channel->curr += avail; return avail; } else { - nread = caml_do_read(channel->fd, channel->buff, - channel->end - channel->buff); + nread = do_read(channel->fd, channel->flags, channel->buff, + channel->end - channel->buff); channel->offset += nread; channel->max = channel->buff + nread; if (n > nread) n = nread; @@ -407,7 +393,8 @@ CAMLexport intnat caml_input_scan_line(struct channel *channel) return -(channel->max - channel->curr); } /* Fill the buffer as much as possible */ - n = caml_do_read(channel->fd, channel->max, channel->end - channel->max); + n = do_read(channel->fd, channel->flags, + channel->max, channel->end - channel->max); if (n == 0) { /* End-of-file encountered. Return the number of characters in the buffer, with negative sign since we haven't encountered @@ -603,6 +590,15 @@ CAMLprim value caml_ml_set_binary_mode(value vchannel, value mode) { #if defined(_WIN32) || defined(__CYGWIN__) struct channel * channel = Channel(vchannel); +#if defined(_WIN32) + /* The implementation of [caml_read_fd] and [caml_write_fd] in win32.c + doesn't support socket I/O with CRLF conversion. */ + if (channel->flags & CHANNEL_FLAG_FROM_SOCKET != 0 + && ! Bool_val(mode)) { + errno = EINVAL; + caml_sys_error(NO_ARG); + } +#endif if (setmode(channel->fd, Bool_val(mode) ? O_BINARY : O_TEXT) == -1) caml_sys_error(NO_ARG); #endif @@ -778,7 +774,7 @@ CAMLprim value caml_ml_input(value vchannel, value buff, value vstart, channel->curr += avail; n = avail; } else { - nread = caml_do_read(channel->fd, channel->buff, + nread = do_read(channel->fd, channel->flags, channel->buff, channel->end - channel->buff); channel->offset += nread; channel->max = channel->buff + nread; |