[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Guile-commits] 01/23: add (ice-9 nio)
From: |
Andy Wingo |
Subject: |
[Guile-commits] 01/23: add (ice-9 nio) |
Date: |
Thu, 24 Mar 2016 14:26:02 +0000 |
wingo pushed a commit to branch wip-ethreads
in repository guile.
commit c1f69f19ac3584ee24a772f59d9078e5f5259a74
Author: Andy Wingo <address@hidden>
Date: Fri Mar 16 18:13:06 2012 +0100
add (ice-9 nio)
* module/ice-9/nio.scm: New module, providing nonblocking I/O
primitives.
* libguile/nio.c:
* libguile/nio.h: New files, providing non-blocking read(2), write(2),
and accept(2) primitives.
* libguile/init.c:
* libguile/Makefile.am:
* module/Makefile.am: Add to build.
---
libguile/Makefile.am | 2 +
libguile/init.c | 2 +
libguile/nio.c | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++
libguile/nio.h | 30 ++++++++
module/Makefile.am | 1 +
module/ice-9/nio.scm | 46 ++++++++++++
6 files changed, 278 insertions(+), 0 deletions(-)
diff --git a/libguile/Makefile.am b/libguile/Makefile.am
index 3bc9952..ac7aad3 100644
--- a/libguile/Makefile.am
+++ b/libguile/Makefile.am
@@ -175,6 +175,7 @@ address@hidden@_la_SOURCES =
\
mallocs.c \
memoize.c \
modules.c \
+ nio.c \
null-threads.c \
numbers.c \
objprop.c \
@@ -620,6 +621,7 @@ modinclude_HEADERS = \
memoize.h \
modules.h \
net_db.h \
+ nio.h \
null-threads.h \
numbers.h \
objprop.h \
diff --git a/libguile/init.c b/libguile/init.c
index dd63574..da6e145 100644
--- a/libguile/init.c
+++ b/libguile/init.c
@@ -82,6 +82,7 @@
#include "libguile/memoize.h"
#include "libguile/modules.h"
#include "libguile/net_db.h"
+#include "libguile/nio.h"
#include "libguile/numbers.h"
#include "libguile/loader.h"
#include "libguile/objprop.h"
@@ -402,6 +403,7 @@ scm_i_init_guile (void *base)
scm_register_foreign_object ();
scm_register_srfi_1 ();
scm_register_srfi_60 ();
+ scm_register_nio ();
scm_register_poll ();
scm_init_strings (); /* Requires array-handle */
diff --git a/libguile/nio.c b/libguile/nio.c
new file mode 100644
index 0000000..bebb059
--- /dev/null
+++ b/libguile/nio.c
@@ -0,0 +1,197 @@
+/* Copyright (C) 2016 Free Software Foundation, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+
+
+
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libguile/_scm.h"
+#include "libguile/bytevectors.h"
+#include "libguile/error.h"
+#include "libguile/numbers.h"
+#include "libguile/socket.h"
+#include "libguile/validate.h"
+
+#include "libguile/nio.h"
+
+#ifdef HAVE_WINSOCK2_H
+#include <winsock2.h>
+#else
+#include <sys/socket.h>
+#ifdef HAVE_UNIX_DOMAIN_SOCKETS
+#include <sys/un.h>
+#endif
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#endif
+
+
+
+/* {Non-blocking I/O}
+ */
+
+/* Read COUNT bytes from FD into BV, and write them at POS. Return the
+ number of bytes read, or -1 if no bytes could be read without
+ blocking. A return value of 0 indicates EOF.
+ */
+static SCM
+scm_nio_read (SCM fd, SCM bv, SCM pos, SCM count)
+#define FUNC_NAME "nio-read"
+{
+ int c_fd;
+ ssize_t rv;
+ signed char *data;
+ size_t c_pos, c_count;
+ int try_again;
+
+ c_fd = scm_to_int (fd);
+ SCM_VALIDATE_BYTEVECTOR (SCM_ARG2, bv);
+ data = SCM_BYTEVECTOR_CONTENTS (bv);
+ c_pos = scm_to_size_t (pos);
+ c_count = scm_to_size_t (count);
+
+ if (SCM_UNLIKELY (SCM_BYTEVECTOR_LENGTH (bv) < c_pos))
+ SCM_OUT_OF_RANGE (SCM_ARG3, pos);
+ if (SCM_UNLIKELY (c_count > SCM_BYTEVECTOR_LENGTH (bv) - c_pos))
+ SCM_OUT_OF_RANGE (SCM_ARG4, count);
+
+ data += c_pos;
+
+ rv = read (c_fd, data, c_count);
+ try_again = (errno == EWOULDBLOCK || errno == EAGAIN);
+
+ if (rv < 0 && !try_again)
+ SCM_SYSERROR;
+ if (rv <= 0 && try_again)
+ return scm_from_ssize_t (-1);
+ else
+ return scm_from_ssize_t (rv);
+}
+#undef FUNC_NAME
+
+/* Write to FD the COUNT bytes from BV starting at POS. Return the
+ number of bytes written, which may be less than COUNT if a write would
+ block.
+ */
+static SCM
+scm_nio_write (SCM fd, SCM bv, SCM pos, SCM count)
+#define FUNC_NAME "nio-write"
+{
+ int c_fd;
+ ssize_t rv;
+ signed char *data;
+ size_t c_pos, c_count;
+ int try_again;
+
+ c_fd = scm_to_int (fd);
+ SCM_VALIDATE_BYTEVECTOR (SCM_ARG2, bv);
+ data = SCM_BYTEVECTOR_CONTENTS (bv);
+ c_pos = scm_to_size_t (pos);
+ c_count = scm_to_size_t (count);
+
+ if (SCM_UNLIKELY (SCM_BYTEVECTOR_LENGTH (bv) < c_pos))
+ SCM_OUT_OF_RANGE (SCM_ARG3, pos);
+ if (SCM_UNLIKELY (c_count > SCM_BYTEVECTOR_LENGTH (bv) - c_pos))
+ SCM_OUT_OF_RANGE (SCM_ARG4, count);
+
+ data += c_pos;
+
+ rv = write (c_fd, data, c_count);
+ try_again = (errno == EWOULDBLOCK || errno == EAGAIN);
+
+ if (rv < 0 && !try_again)
+ SCM_SYSERROR;
+
+ return scm_from_ssize_t ((rv < 0) ? 0 : rv);
+}
+#undef FUNC_NAME
+
+/* The largest possible socket address. Wrapping it in a union guarantees
+ that the compiler will make it suitably aligned. */
+typedef union
+{
+ struct sockaddr sockaddr;
+ struct sockaddr_in sockaddr_in;
+
+#ifdef HAVE_UNIX_DOMAIN_SOCKETS
+ struct sockaddr_un sockaddr_un;
+#endif
+#ifdef HAVE_IPV6
+ struct sockaddr_in6 sockaddr_in6;
+#endif
+} scm_t_max_sockaddr;
+
+/* Like @code{accept}, but instead of returning a pair whose
+ @emph{car} is a port, returns a pair whose @emph{car} is a
+ file descriptor. Also, if the @code{accept} call failed with
+ @code{EAGAIN} or @code{EWOULDBLOCK}, returns @code{#f} instead
+ of throwing an exception. */
+static SCM
+scm_nio_accept (SCM fd)
+#define FUNC_NAME "nio-accept"
+{
+ int c_fd;
+ int newfd;
+ socklen_t addr_size = sizeof (scm_t_max_sockaddr);
+ scm_t_max_sockaddr addr;
+
+ c_fd = scm_to_int (fd);
+ newfd = accept (c_fd, (struct sockaddr *) &addr, &addr_size);
+
+ if (newfd >= 0)
+ return scm_cons (scm_from_int (newfd),
+ scm_from_sockaddr ((struct sockaddr *) &addr, addr_size));
+ else if (errno == EAGAIN || errno == EWOULDBLOCK)
+ return SCM_BOOL_F;
+ else
+ SCM_SYSERROR;
+}
+#undef FUNC_NAME
+
+
+
+
+/* Low-level helpers for (ice-9 nio). */
+static void
+scm_init_nio (void)
+{
+ scm_c_define_gsubr ("%nio-read", 4, 0, 0, scm_nio_read);
+ scm_c_define_gsubr ("%nio-write", 4, 0, 0, scm_nio_write);
+ scm_c_define_gsubr ("%nio-accept", 1, 0, 0, scm_nio_accept);
+}
+
+void
+scm_register_nio (void)
+{
+ scm_c_register_extension ("libguile-" SCM_EFFECTIVE_VERSION,
+ "scm_init_nio",
+ (scm_t_extension_init_func) scm_init_nio,
+ NULL);
+}
+
+/*
+ Local Variables:
+ c-file-style: "gnu"
+ End:
+*/
diff --git a/libguile/nio.h b/libguile/nio.h
new file mode 100644
index 0000000..152bebb
--- /dev/null
+++ b/libguile/nio.h
@@ -0,0 +1,30 @@
+#ifndef SCM_NIO_H
+#define SCM_NIO_H
+
+/* Copyright (C) 2016 Free Software Foundation, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+
+
+#include "libguile/__scm.h"
+
+
+
+SCM_INTERNAL void scm_register_nio (void);
+
+#endif /* SCM_NIO_H */
diff --git a/module/Makefile.am b/module/Makefile.am
index 6cb1603..6120760 100644
--- a/module/Makefile.am
+++ b/module/Makefile.am
@@ -76,6 +76,7 @@ SOURCES = \
ice-9/mapping.scm \
ice-9/match.scm \
ice-9/networking.scm \
+ ice-9/nio.scm \
ice-9/null.scm \
ice-9/occam-channel.scm \
ice-9/optargs.scm \
diff --git a/module/ice-9/nio.scm b/module/ice-9/nio.scm
new file mode 100644
index 0000000..b2f0e71
--- /dev/null
+++ b/module/ice-9/nio.scm
@@ -0,0 +1,46 @@
+;; Non-Blocking I/O
+
+;;;; Copyright (C) 2016 Free Software Foundation, Inc.
+;;;;
+;;;; This library is free software; you can redistribute it and/or
+;;;; modify it under the terms of the GNU Lesser General Public
+;;;; License as published by the Free Software Foundation; either
+;;;; version 3 of the License, or (at your option) any later version.
+;;;;
+;;;; This library is distributed in the hope that it will be useful,
+;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;;;; Lesser General Public License for more details.
+;;;;
+;;;; You should have received a copy of the GNU Lesser General Public
+;;;; License along with this library; if not, write to the Free Software
+;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
+;;;;
+
+(define-module (ice-9 nio)
+ #:export (nio-read
+ nio-write
+ nio-accept))
+
+(eval-when (eval load compile)
+ (load-extension (string-append "libguile-" (effective-version))
+ "scm_init_nio"))
+
+(define (nio-read fd bv pos count)
+ "Read @var{count} bytes from @var{fd} into @var{bv}, and write them at
address@hidden Return the number of bytes read, or -1 if no bytes could be
+read without blocking. A return value of 0 indicates EOF."
+ (%nio-read fd bv pos count))
+
+(define (nio-write fd bv pos count)
+ "Write to @var{fd} the @var{count} bytes from @var{bv} starting at
address@hidden Return the number of bytes written, which may be less than
address@hidden if a write would block."
+ (%nio-write fd bv pos count))
+
+(define (nio-accept fd)
+ "Accept a new connection on the socket whose file descriptor is
address@hidden Return a pair whose @emph{car} is a file descriptor of the
+new client socket, unless the @code{accept} call would have blocked, in
+which case return @code{#f}."
+ (%nio-accept fd))
- [Guile-commits] 13/23: add latin1 chars and strings to eports, (continued)
- [Guile-commits] 13/23: add latin1 chars and strings to eports, Andy Wingo, 2016/03/24
- [Guile-commits] 18/23: (web server ethreads) TCP_NODELAY tweak, Andy Wingo, 2016/03/24
- [Guile-commits] 05/23: http: allow custom read-line / continuation-line? functions, Andy Wingo, 2016/03/24
- [Guile-commits] 06/23: setsockopt can take an fd, Andy Wingo, 2016/03/24
- [Guile-commits] 10/23: EOF fix for continuation-line?, Andy Wingo, 2016/03/24
- [Guile-commits] 19/23: nio: add non-blocking connect, Andy Wingo, 2016/03/24
- [Guile-commits] 08/23: add #:limit to get-bytevector-delimited, Andy Wingo, 2016/03/24
- [Guile-commits] 11/23: socket: TCP_CORK, TCP_NODELAY, Andy Wingo, 2016/03/24
- [Guile-commits] 23/23: virtualize read/write/close operations in <eport>, Andy Wingo, 2016/03/24
- [Guile-commits] 15/23: (web server ethreads): more use of latin1 accessors, Andy Wingo, 2016/03/24
- [Guile-commits] 01/23: add (ice-9 nio),
Andy Wingo <=
- [Guile-commits] 20/23: eports: nonblocking connect-eport, Andy Wingo, 2016/03/24
- [Guile-commits] 14/23: refactoring to (web server ethreads) read-http-line, Andy Wingo, 2016/03/24
- [Guile-commits] 02/23: add (ice-9 eports), Andy Wingo, 2016/03/24
- [Guile-commits] 17/23: getsockopt: allow raw file descriptors, Andy Wingo, 2016/03/24
- [Guile-commits] 16/23: eports: add put-utf8-char, put-utf8-string, Andy Wingo, 2016/03/24
- [Guile-commits] 03/23: add (ice-9 epoll), Andy Wingo, 2016/03/24
- [Guile-commits] 21/23: eports tweak, Andy Wingo, 2016/03/24
- [Guile-commits] 07/23: add (web server ethreads), Andy Wingo, 2016/03/24
- [Guile-commits] 22/23: add examples/ethreads/memcached-{client, server}, Andy Wingo, 2016/03/24