diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-14 20:15:04 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-14 20:15:04 +0000 |
commit | 95b149fd51f86b35f7a6e82d28602a479319943e (patch) | |
tree | 8d7245531a5a7415aca8d276ddcd1dde96652404 /libgo | |
parent | 53293a4998d9225b50213ea0c57246c5024d7fbf (diff) | |
download | gcc-95b149fd51f86b35f7a6e82d28602a479319943e.tar.gz |
runtime: Add netpoll code that uses select.
Required for Solaris support.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204817 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo')
-rw-r--r-- | libgo/Makefile.am | 31 | ||||
-rw-r--r-- | libgo/Makefile.in | 49 | ||||
-rw-r--r-- | libgo/runtime/malloc.h | 1 | ||||
-rw-r--r-- | libgo/runtime/mgc0.c | 1 | ||||
-rw-r--r-- | libgo/runtime/netpoll_epoll.c | 7 | ||||
-rw-r--r-- | libgo/runtime/netpoll_kqueue.c | 10 | ||||
-rw-r--r-- | libgo/runtime/netpoll_select.c | 223 | ||||
-rw-r--r-- | libgo/runtime/netpoll_stub.c | 7 |
8 files changed, 270 insertions, 59 deletions
diff --git a/libgo/Makefile.am b/libgo/Makefile.am index 489eafd6676..052cded183b 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -413,12 +413,12 @@ endif endif if LIBGO_IS_LINUX -runtime_netpoll_files = netpoll.c runtime/netpoll_epoll.c +runtime_netpoll_files = runtime/netpoll_epoll.c else -if LIBGO_IS_DARWIN -runtime_netpoll_files = netpoll.c runtime/netpoll_kqueue.c +if LIBGO_IS_SOLARIS +runtime_netpoll_files = runtime/netpoll_select.c else -runtime_netpoll_files = runtime/netpoll_stub.c +runtime_netpoll_files = runtime/netpoll_kqueue.c endif endif @@ -515,6 +515,7 @@ runtime_files = \ malloc.c \ map.c \ mprof.c \ + netpoll.c \ reflect.c \ runtime1.c \ sema.c \ @@ -670,26 +671,6 @@ go_mime_files = \ go/mime/type.go \ go/mime/type_unix.go -if LIBGO_IS_RTEMS -go_net_fd_os_file = go/net/fd_select.go -go_net_newpollserver_file = go/net/newpollserver_rtems.go -else # !LIBGO_IS_RTEMS -if LIBGO_IS_LINUX -go_net_fd_os_file = -go_net_newpollserver_file = -else # !LIBGO_IS_LINUX && !LIBGO_IS_RTEMS -if LIBGO_IS_NETBSD -go_net_fd_os_file = -go_net_newpollserver_file = -else # !LIBGO_IS_NETBSD && !LIBGO_IS_LINUX && !LIBGO_IS_RTEMS -# By default use select with pipes. Most systems should have -# something better. -go_net_fd_os_file = go/net/fd_select.go -go_net_newpollserver_file = -endif # !LIBGO_IS_NETBSD -endif # !LIBGO_IS_LINUX -endif # !LIBGO_IS_RTEMS - if LIBGO_IS_LINUX go_net_cgo_file = go/net/cgo_linux.go go_net_sock_file = go/net/sock_linux.go @@ -787,10 +768,8 @@ go_net_files = \ go/net/dnsclient_unix.go \ go/net/dnsconfig_unix.go \ go/net/dnsmsg.go \ - $(go_net_newpollserver_file) \ go/net/fd_mutex.go \ go/net/fd_unix.go \ - $(go_net_fd_os_file) \ go/net/file_unix.go \ go/net/hosts.go \ go/net/interface.go \ diff --git a/libgo/Makefile.in b/libgo/Makefile.in index 20caecabfec..e633b60ecf3 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -179,12 +179,9 @@ libgo_la_DEPENDENCIES = $(am__DEPENDENCIES_2) \ @LIBGO_IS_LINUX_TRUE@am__objects_1 = lock_futex.lo thread-linux.lo @HAVE_SYS_MMAN_H_FALSE@am__objects_2 = mem_posix_memalign.lo @HAVE_SYS_MMAN_H_TRUE@am__objects_2 = mem.lo -@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_LINUX_FALSE@am__objects_3 = \ -@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_LINUX_FALSE@ netpoll_stub.lo -@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@am__objects_3 = \ -@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@ netpoll.lo \ -@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@ netpoll_kqueue.lo -@LIBGO_IS_LINUX_TRUE@am__objects_3 = netpoll.lo netpoll_epoll.lo +@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@am__objects_3 = netpoll_kqueue.lo +@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@am__objects_3 = netpoll_select.lo +@LIBGO_IS_LINUX_TRUE@am__objects_3 = netpoll_epoll.lo @LIBGO_IS_RTEMS_TRUE@am__objects_4 = rtems-task-variable-add.lo @LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@am__objects_5 = getncpu-none.lo @LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@am__objects_5 = getncpu-bsd.lo @@ -220,8 +217,9 @@ am__objects_6 = go-append.lo go-assert.lo go-assert-interface.lo \ mfinal.lo mfixalloc.lo mgc0.lo mheap.lo msize.lo \ $(am__objects_3) panic.lo parfor.lo print.lo proc.lo \ runtime.lo signal_unix.lo thread.lo yield.lo $(am__objects_4) \ - iface.lo malloc.lo map.lo mprof.lo reflect.lo runtime1.lo \ - sema.lo sigqueue.lo string.lo time.lo $(am__objects_5) + iface.lo malloc.lo map.lo mprof.lo netpoll.lo reflect.lo \ + runtime1.lo sema.lo sigqueue.lo string.lo time.lo \ + $(am__objects_5) am_libgo_la_OBJECTS = $(am__objects_6) libgo_la_OBJECTS = $(am_libgo_la_OBJECTS) libgo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ @@ -752,9 +750,9 @@ toolexeclibgounicode_DATA = \ @LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@runtime_getncpu_file = runtime/getncpu-irix.c @LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@runtime_getncpu_file = runtime/getncpu-bsd.c @LIBGO_IS_LINUX_TRUE@runtime_getncpu_file = runtime/getncpu-linux.c -@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_LINUX_FALSE@runtime_netpoll_files = runtime/netpoll_stub.c -@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_LINUX_FALSE@runtime_netpoll_files = netpoll.c runtime/netpoll_kqueue.c -@LIBGO_IS_LINUX_TRUE@runtime_netpoll_files = netpoll.c runtime/netpoll_epoll.c +@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@runtime_netpoll_files = runtime/netpoll_kqueue.c +@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@runtime_netpoll_files = runtime/netpoll_select.c +@LIBGO_IS_LINUX_TRUE@runtime_netpoll_files = runtime/netpoll_epoll.c runtime_files = \ runtime/go-append.c \ runtime/go-assert.c \ @@ -848,6 +846,7 @@ runtime_files = \ malloc.c \ map.c \ mprof.c \ + netpoll.c \ reflect.c \ runtime1.c \ sema.c \ @@ -962,16 +961,6 @@ go_mime_files = \ go/mime/type.go \ go/mime/type_unix.go -# By default use select with pipes. Most systems should have -# something better. -@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_RTEMS_FALSE@go_net_fd_os_file = go/net/fd_select.go -@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_RTEMS_FALSE@go_net_fd_os_file = -@LIBGO_IS_LINUX_TRUE@@LIBGO_IS_RTEMS_FALSE@go_net_fd_os_file = -@LIBGO_IS_RTEMS_TRUE@go_net_fd_os_file = go/net/fd_select.go -@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_RTEMS_FALSE@go_net_newpollserver_file = -@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_RTEMS_FALSE@go_net_newpollserver_file = -@LIBGO_IS_LINUX_TRUE@@LIBGO_IS_RTEMS_FALSE@go_net_newpollserver_file = -@LIBGO_IS_RTEMS_TRUE@go_net_newpollserver_file = go/net/newpollserver_rtems.go @LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_file = go/net/cgo_bsd.go @LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_file = go/net/cgo_netbsd.go @LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_file = go/net/cgo_bsd.go @@ -1019,10 +1008,8 @@ go_net_files = \ go/net/dnsclient_unix.go \ go/net/dnsconfig_unix.go \ go/net/dnsmsg.go \ - $(go_net_newpollserver_file) \ go/net/fd_mutex.go \ go/net/fd_unix.go \ - $(go_net_fd_os_file) \ go/net/file_unix.go \ go/net/hosts.go \ go/net/interface.go \ @@ -2483,7 +2470,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netpoll.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netpoll_epoll.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netpoll_kqueue.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netpoll_stub.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netpoll_select.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/panic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parfor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Plo@am__quote@ @@ -3111,13 +3098,6 @@ msize.lo: runtime/msize.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o msize.lo `test -f 'runtime/msize.c' || echo '$(srcdir)/'`runtime/msize.c -netpoll_stub.lo: runtime/netpoll_stub.c -@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT netpoll_stub.lo -MD -MP -MF $(DEPDIR)/netpoll_stub.Tpo -c -o netpoll_stub.lo `test -f 'runtime/netpoll_stub.c' || echo '$(srcdir)/'`runtime/netpoll_stub.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/netpoll_stub.Tpo $(DEPDIR)/netpoll_stub.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/netpoll_stub.c' object='netpoll_stub.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o netpoll_stub.lo `test -f 'runtime/netpoll_stub.c' || echo '$(srcdir)/'`runtime/netpoll_stub.c - netpoll_kqueue.lo: runtime/netpoll_kqueue.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT netpoll_kqueue.lo -MD -MP -MF $(DEPDIR)/netpoll_kqueue.Tpo -c -o netpoll_kqueue.lo `test -f 'runtime/netpoll_kqueue.c' || echo '$(srcdir)/'`runtime/netpoll_kqueue.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/netpoll_kqueue.Tpo $(DEPDIR)/netpoll_kqueue.Plo @@ -3125,6 +3105,13 @@ netpoll_kqueue.lo: runtime/netpoll_kqueue.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o netpoll_kqueue.lo `test -f 'runtime/netpoll_kqueue.c' || echo '$(srcdir)/'`runtime/netpoll_kqueue.c +netpoll_select.lo: runtime/netpoll_select.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT netpoll_select.lo -MD -MP -MF $(DEPDIR)/netpoll_select.Tpo -c -o netpoll_select.lo `test -f 'runtime/netpoll_select.c' || echo '$(srcdir)/'`runtime/netpoll_select.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/netpoll_select.Tpo $(DEPDIR)/netpoll_select.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/netpoll_select.c' object='netpoll_select.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o netpoll_select.lo `test -f 'runtime/netpoll_select.c' || echo '$(srcdir)/'`runtime/netpoll_select.c + netpoll_epoll.lo: runtime/netpoll_epoll.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT netpoll_epoll.lo -MD -MP -MF $(DEPDIR)/netpoll_epoll.Tpo -c -o netpoll_epoll.lo `test -f 'runtime/netpoll_epoll.c' || echo '$(srcdir)/'`runtime/netpoll_epoll.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/netpoll_epoll.Tpo $(DEPDIR)/netpoll_epoll.Plo diff --git a/libgo/runtime/malloc.h b/libgo/runtime/malloc.h index 45c4c09c147..e1a5be99919 100644 --- a/libgo/runtime/malloc.h +++ b/libgo/runtime/malloc.h @@ -515,3 +515,4 @@ void runtime_memorydump(void); void runtime_proc_scan(void (*)(Obj)); void runtime_time_scan(void (*)(Obj)); +void runtime_netpoll_scan(void (*)(Obj)); diff --git a/libgo/runtime/mgc0.c b/libgo/runtime/mgc0.c index 3edcee9c397..865f1930489 100644 --- a/libgo/runtime/mgc0.c +++ b/libgo/runtime/mgc0.c @@ -1491,6 +1491,7 @@ addroots(void) runtime_proc_scan(addroot); runtime_MProf_Mark(addroot); runtime_time_scan(addroot); + runtime_netpoll_scan(addroot); // MSpan.types allspans = runtime_mheap.allspans; diff --git a/libgo/runtime/netpoll_epoll.c b/libgo/runtime/netpoll_epoll.c index b98aa818c89..2acbca32322 100644 --- a/libgo/runtime/netpoll_epoll.c +++ b/libgo/runtime/netpoll_epoll.c @@ -11,6 +11,7 @@ #include "runtime.h" #include "defs.h" +#include "malloc.h" #ifndef EPOLLRDHUP #define EPOLLRDHUP 0x2000 @@ -156,3 +157,9 @@ retry: goto retry; return gp; } + +void +runtime_netpoll_scan(void (*addroot)(Obj)) +{ + USED(addroot); +} diff --git a/libgo/runtime/netpoll_kqueue.c b/libgo/runtime/netpoll_kqueue.c index 78901611884..5d3f85617b6 100644 --- a/libgo/runtime/netpoll_kqueue.c +++ b/libgo/runtime/netpoll_kqueue.c @@ -5,8 +5,8 @@ // +build darwin dragonfly freebsd netbsd openbsd #include "runtime.h" -#include "defs_GOOS_GOARCH.h" -#include "os_GOOS.h" +#include "defs.h" +#include "malloc.h" // Integrated network poller (kqueue-based implementation). @@ -102,3 +102,9 @@ retry: goto retry; return gp; } + +void +runtime_netpoll_scan(void (*addroot)(Obj)) +{ + USED(addroot); +} diff --git a/libgo/runtime/netpoll_select.c b/libgo/runtime/netpoll_select.c new file mode 100644 index 00000000000..c330f28418f --- /dev/null +++ b/libgo/runtime/netpoll_select.c @@ -0,0 +1,223 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build solaris + +#include "config.h" + +#include <errno.h> +#include <sys/times.h> +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> + +#ifdef HAVE_SYS_SELECT_H +#include <sys/select.h> +#endif + +#include "runtime.h" +#include "malloc.h" + +static Lock selectlock; +static int rdwake; +static int wrwake; +static fd_set fds; +static PollDesc **data; +static int allocated; + +void +runtime_netpollinit(void) +{ + int p[2]; + int fl; + + FD_ZERO(&fds); + allocated = 128; + data = runtime_mallocgc(allocated * sizeof(PollDesc *), 0, + FlagNoScan|FlagNoProfiling|FlagNoInvokeGC); + + if(pipe(p) < 0) + runtime_throw("netpollinit: failed to create pipe"); + rdwake = p[0]; + wrwake = p[1]; + + fl = fcntl(rdwake, F_GETFL); + if(fl < 0) + runtime_throw("netpollinit: fcntl failed"); + fl |= O_NONBLOCK; + if(fcntl(rdwake, F_SETFL, fl)) + runtime_throw("netpollinit: fcntl failed"); + fcntl(rdwake, F_SETFD, FD_CLOEXEC); + + fl = fcntl(wrwake, F_GETFL); + if(fl < 0) + runtime_throw("netpollinit: fcntl failed"); + fl |= O_NONBLOCK; + if(fcntl(wrwake, F_SETFL, fl)) + runtime_throw("netpollinit: fcntl failed"); + fcntl(wrwake, F_SETFD, FD_CLOEXEC); + + FD_SET(rdwake, &fds); +} + +int32 +runtime_netpollopen(uintptr fd, PollDesc *pd) +{ + byte b; + + runtime_lock(&selectlock); + + if((int)fd >= allocated) { + int c; + PollDesc **n; + + c = allocated; + + runtime_unlock(&selectlock); + + while((int)fd >= c) + c *= 2; + n = runtime_mallocgc(c * sizeof(PollDesc *), 0, + FlagNoScan|FlagNoProfiling|FlagNoInvokeGC); + + runtime_lock(&selectlock); + + if(c > allocated) { + __builtin_memcpy(n, data, allocated * sizeof(PollDesc *)); + allocated = c; + data = n; + } + } + FD_SET(fd, &fds); + data[fd] = pd; + + runtime_unlock(&selectlock); + + b = 0; + write(wrwake, &b, sizeof b); + + return 0; +} + +int32 +runtime_netpollclose(uintptr fd) +{ + byte b; + + runtime_lock(&selectlock); + + FD_CLR(fd, &fds); + data[fd] = nil; + + runtime_unlock(&selectlock); + + b = 0; + write(wrwake, &b, sizeof b); + + return 0; +} + +G* +runtime_netpoll(bool block) +{ + fd_set rfds, wfds, efds, tfds; + struct timeval timeout; + struct timeval *pt; + int max, c, i; + G *gp; + int32 mode; + byte b; + struct stat st; + + retry: + runtime_lock(&selectlock); + + max = allocated; + + if(max == 0) { + runtime_unlock(&selectlock); + return nil; + } + + __builtin_memcpy(&rfds, &fds, sizeof fds); + + runtime_unlock(&selectlock); + + __builtin_memcpy(&wfds, &rfds, sizeof fds); + FD_CLR(rdwake, &wfds); + __builtin_memcpy(&efds, &wfds, sizeof fds); + + __builtin_memcpy(&tfds, &wfds, sizeof fds); + + __builtin_memset(&timeout, 0, sizeof timeout); + pt = &timeout; + if(block) + pt = nil; + + c = select(max, &rfds, &wfds, &efds, pt); + if(c < 0) { + if(errno == EBADF) { + // Some file descriptor has been closed. + // Check each one, and treat each closed + // descriptor as ready for read/write. + c = 0; + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&efds); + for(i = 0; i < max; i++) { + if(FD_ISSET(i, &tfds) + && fstat(i, &st) < 0 + && errno == EBADF) { + FD_SET(i, &rfds); + FD_SET(i, &wfds); + c += 2; + } + } + } + else { + if(errno != EINTR) + runtime_printf("runtime: select failed with %d\n", errno); + goto retry; + } + } + gp = nil; + for(i = 0; i < max && c > 0; i++) { + mode = 0; + if(FD_ISSET(i, &rfds)) { + mode += 'r'; + --c; + } + if(FD_ISSET(i, &wfds)) { + mode += 'w'; + --c; + } + if(FD_ISSET(i, &efds)) { + mode = 'r' + 'w'; + --c; + } + if(i == rdwake) { + while(read(rdwake, &b, sizeof b) > 0) + ; + continue; + } + if(mode) { + PollDesc *pd; + + runtime_lock(&selectlock); + pd = data[i]; + runtime_unlock(&selectlock); + if(pd != nil) + runtime_netpollready(&gp, pd, mode); + } + } + if(block && gp == nil) + goto retry; + return gp; +} + +void +runtime_netpoll_scan(void (*addroot)(Obj)) +{ + addroot((Obj){(byte*)&data, sizeof data, 0}); +} diff --git a/libgo/runtime/netpoll_stub.c b/libgo/runtime/netpoll_stub.c index 84eef754c8d..a88c9f5b9c2 100644 --- a/libgo/runtime/netpoll_stub.c +++ b/libgo/runtime/netpoll_stub.c @@ -5,6 +5,7 @@ // +build plan9 #include "runtime.h" +#include "malloc.h" // Polls for ready network connections. // Returns list of goroutines that become runnable. @@ -16,3 +17,9 @@ runtime_netpoll(bool block) USED(block); return nil; } + +void +runtime_netpoll_scan(void (*addroot)(Obj)) +{ + USED(addroot); +} |