summaryrefslogtreecommitdiff
path: root/byterun/io.c
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>2015-11-30 11:42:16 +0100
committerXavier Leroy <xavier.leroy@inria.fr>2015-11-30 11:42:16 +0100
commit15ac614a894d2eb9414f68b449d7f153f5882f94 (patch)
tree66db7279536e6293e5dbec1b72dedf22ee26ebad /byterun/io.c
parent35dc44a00f1beed49c0affecfd38dbd313a24113 (diff)
downloadocaml-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.c64
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;