]> gitweb.factorcode.org Git - factor.git/commitdiff
I/O system now uses select()
authorSlava Pestov <slava@factorcode.org>
Mon, 13 Jun 2005 05:42:16 +0000 (05:42 +0000)
committerSlava Pestov <slava@factorcode.org>
Mon, 13 Jun 2005 05:42:16 +0000 (05:42 +0000)
CHANGES.txt
library/alien/aliens.factor
library/collections/hashtables.factor
library/unix/io.factor
library/unix/sockets.factor
library/unix/syscalls-freebsd.factor
library/unix/syscalls-linux.factor
library/unix/syscalls-macosx.factor
library/unix/syscalls.factor
native/io.c
native/io.h

index fe97232ba299a86795a83f4f21c24b24e7620509..512a2ba9d060f45d0425be5d2263156e9f255934 100644 (file)
@@ -3,6 +3,8 @@ Factor 0.75:
 
 + Runtime and core library
 
+- Fix for a fatal bug where Factor was not functional on Mac OS X 10.4.
+
 - New generational garbage collector. There are two command line
   switches for controlling it:
 
index d9904f4a608d1026014dbb8e723851266f8168b9..3c30e778de1c8b5a7872c0d5a4380b951b970985 100644 (file)
@@ -52,18 +52,4 @@ M: alien = ( obj obj -- ? )
 : library-abi ( library -- abi )
     library [ [ "abi" get ] bind ] [ "cdecl" ] ifte* ;
 
-! This will go elsewhere soon
-: byte-bit ( n alien -- byte bit )
-    over -3 shift alien-unsigned-1 swap 7 bitand ;
-
-: bit-nth ( n alien -- ? )
-    byte-bit 1 swap shift bitand 0 > ;
-
-: set-bit ( ? byte bit -- byte )
-    1 swap shift rot [ bitor ] [ bitnot bitand ] ifte ;
-
-: set-bit-nth ( ? n alien -- )
-    [ byte-bit set-bit ] 2keep
-    swap -3 shift set-alien-unsigned-1 ;
-
 : ALIEN: scan-word <alien> swons ; parsing
index 91db3efe023436e1411c2481844ca93811ccc1f6..7cbcbc5d0785640bde10cc8c8f6f36e27e3140ed 100644 (file)
@@ -129,6 +129,9 @@ IN: hashtables
 : hash-each ( hash quot -- )
     swap hash-array [ swap each ] each-with ; inline
 
+: hash-each-with ( obj hash quot -- | quot: obj elt -- )
+    swap [ with ] hash-each 2drop ; inline
+
 : hash-subset ( hash quot -- hash | quot: [[ k v ]] -- ? )
     >r hash>alist r> subset alist>hash ;
 
index 620f30b8c4b41f7cc5cc59cdf3aebe9e0c12595d..30eec1149cba2897c26666a172cf968a8a7c94db 100644 (file)
@@ -1,17 +1,41 @@
 ! Copyright (C) 2004, 2005 Slava Pestov.
 ! See http://factor.sf.net/license.txt for BSD license.
 IN: io-internals
-USING: alien errors generic hashtables kernel lists math
-sequences streams strings threads unix-internals vectors ;
+USING: alien assembler errors generic hashtables kernel
+kernel-internals lists math sequences streams strings threads
+unix-internals vectors ;
 
 ! We want namespaces::bind to shadow the bind system call from
 ! unix-internals
 USING: namespaces ;
 
+! This will go elsewhere soon
+: byte-bit ( n alien -- byte bit )
+    over -3 shift alien-unsigned-1 swap 7 bitand ;
+
+: <bit-array> ( n -- array )
+    cell / ceiling <byte-array> ;
+
+: bit-nth ( n alien -- ? )
+    byte-bit 1 swap shift bitand 0 > ;
+
+: set-bit ( ? byte bit -- byte )
+    1 swap shift rot [ bitor ] [ bitnot bitand ] ifte ;
+
+: set-bit-nth ( ? n alien -- )
+    [ byte-bit set-bit ] 2keep
+    swap -3 shift set-alien-unsigned-1 ;
+
+! Global variables
+SYMBOL: read-fdset
+SYMBOL: read-tasks
+SYMBOL: write-fdset
+SYMBOL: write-tasks
+
 ! Some general stuff
 : file-mode OCT: 0600 ;
 
-: (io-error) errno strerror throw ;
+: (io-error) err_no strerror throw ;
 
 : check-null ( n -- ) 0 = [ (io-error) ] when ;
 
@@ -52,7 +76,7 @@ M: port set-timeout ( timeout port -- )
 : pending-error ( reader -- ) port-error throw ;
 
 : postpone-error ( reader -- )
-    errno strerror swap set-port-error ;
+    err_no strerror swap set-port-error ;
 
 ! Associates a port with a list of continuations waiting on the
 ! port to finish I/O
@@ -61,26 +85,18 @@ C: io-task ( port -- ) [ set-io-task-port ] keep ;
 
 ! Multiplexer
 GENERIC: do-io-task ( task -- ? )
-GENERIC: io-task-events ( task -- events )
-
-! A hashtable in the global namespace mapping fd numbers to
-! io-tasks. This is not a vector, since we need a quick way
-! to find the number of elements, and a hashtable gives us
-! this with the hash-size call.
-SYMBOL: io-tasks
-
-: io-task ( pollfd -- io-task ) pollfd-fd io-tasks get hash ;
+GENERIC: task-container ( task -- vector )
 
 : io-task-fd io-task-port port-handle ;
 
 : add-io-task ( callback task -- )
     [ >r unit r> set-io-task-callbacks ] keep
-    dup io-task-fd io-tasks get 2dup hash [
+    dup io-task-fd over task-container 2dup hash [
         "Cannot perform multiple I/O ops on the same port" throw
     ] when set-hash ;
 
 : remove-io-task ( task -- )
-    io-task-fd io-tasks get remove-hash ;
+    dup io-task-fd swap task-container remove-hash ;
 
 : pop-callback ( task -- callback )
     dup io-task-callbacks uncons dup [
@@ -89,50 +105,37 @@ SYMBOL: io-tasks
         drop swap remove-io-task
     ] ifte ;
 
-: handle-fd ( pollfd -- quot )
-    io-task dup do-io-task [
-        dup io-task-port touch-port pop-callback
+: handle-fd ( task -- )
+    dup do-io-task [
+        dup io-task-port touch-port pop-callback [ call ] when*
     ] [
-        drop f
+        drop
     ] ifte ;
 
 : timeout? ( port -- ? )
     port-cutoff dup 0 = not swap millis < and ;
 
-: handle-fd? ( pollfd -- ? )
-    dup pollfd-revents 0 = not >r
-    io-task io-task-port timeout? r> or ;
+: handle-fd? ( fdset task -- ? )
+    dup io-task-port timeout?
+    [ 2drop t ] [ io-task-fd swap bit-nth ] ifte ;
 
-: do-io-tasks ( pollfds n -- )
+: handle-fdset ( fdset tasks -- )
     [
-        dup pick pollfd-nth dup handle-fd? [
-            handle-fd [ call ] when*
-        ] [
-            drop
-        ] ifte
-    ] repeat drop ;
-
-: io-task# io-tasks get hash-size ;
+        cdr tuck handle-fd? [ handle-fd ] [ drop ] ifte
+    ] hash-each-with ;
 
-: io-task-list io-tasks get hash-values ;
+: init-fdset ( fdset tasks -- )
+    [ car t swap rot set-bit-nth ] hash-each-with ;
 
-: init-pollfd ( task pollfd -- )
-    over io-task-fd over set-pollfd-fd
-    swap io-task-events swap set-pollfd-events ;
-
-: make-pollfds ( -- pollfds n )
-    io-task# [
-        <pollfd-array> 0 io-task-list [
-            pick pick swap pollfd-nth init-pollfd 1 +
-        ] each drop
-    ] keep ;
+: init-fdsets ( -- read write except )
+    read-fdset get [ read-tasks get init-fdset ] keep
+    write-fdset get [ write-tasks get init-fdset ] keep
+    NULL ;
 
 : io-multiplex ( timeout -- )
-    >r make-pollfds 2dup r> poll drop do-io-tasks ;
-
-: pending-io? ( -- ? )
-    #! Output if there are waiting I/O requests.
-    io-tasks get hash-size 0 > ;
+    >r FD_SETSIZE init-fdsets r> make-timeval select drop
+    read-fdset get read-tasks get handle-fdset
+    write-fdset get write-tasks get handle-fdset ;
 
 ! Readers
 
@@ -225,8 +228,7 @@ M: read-line-task do-io-task ( task -- ? )
         read-line-step
     ] ifte ;
 
-M: read-line-task io-task-events ( task -- events )
-    drop POLLIN ;
+M: read-line-task task-container drop read-tasks get ;
 
 : wait-to-read-line ( port -- )
     dup can-read-line? [
@@ -288,8 +290,7 @@ M: read-task do-io-task ( task -- ? )
         read-step
     ] ifte ;
 
-M: read-task io-task-events ( task -- events )
-    drop POLLIN ;
+M: read-task task-container drop read-tasks get ;
 
 : wait-to-read ( count port -- )
     2dup can-read-count? [
@@ -339,18 +340,16 @@ M: write-task do-io-task
         >port< write-step f
     ] ifte ;
 
-M: write-task io-task-events ( task -- events )
-    drop POLLOUT ;
+M: write-task task-container drop write-tasks get ;
 
 : write-fin ( str writer -- )
     dup pending-error >buffer ;
 
 : add-write-io-task ( callback task -- )
-    dup io-task-fd io-tasks get hash [
+    dup io-task-fd write-tasks get hash [
         dup write-task? [
-            [
-                nip io-task-callbacks cons
-            ] keep set-io-task-callbacks
+            [ nip io-task-callbacks cons ] keep
+            set-io-task-callbacks
         ] [
             drop add-io-task
         ] ifte
@@ -389,7 +388,10 @@ USE: stdio
     #! Should only be called on startup. Calling this at any
     #! other time can have unintended consequences.
     global [
-        <namespace> io-tasks set
+        <namespace> read-tasks set
+        FD_SETSIZE <bit-array> read-fdset set
+        <namespace> write-tasks set
+        FD_SETSIZE <bit-array> write-fdset set
         0 1 t <fd-stream> stdio set
     ] bind
     [ idle-io-task ] in-thread ;
index 7c7714fba1c64e8442b4e6dc85c885ff24e9453c..10e72128067b0604f16c3996b633cf3f7fe9bfa3 100644 (file)
@@ -26,7 +26,7 @@ USING: alien generic kernel math unix-internals ;
 
 : with-socket-fd ( quot -- fd | quot: socket -- n )
     socket-fd [ swap call ] keep  swap 0 < [
-        errno EINPROGRESS = [
+        err_no EINPROGRESS = [
             dup close -1 io-error
         ] unless
     ] when ; inline
@@ -56,8 +56,7 @@ C: accept-task ( port -- task )
 
 M: accept-task do-io-task ( task -- ? ) drop t ;
 
-M: accept-task io-task-events ( task -- events )
-    drop POLLIN ;
+M: accept-task task-container drop read-tasks get ;
 
 : wait-to-accept ( server -- )
     [ swap <accept-task> add-io-task stop ] callcc0 drop ;
index c3a68e4e134f85e7b39c0f9f1bf785fc52d9fb2f..25af8664c3c8c7c9143a94e283be22a8baf3f49c 100644 (file)
@@ -11,9 +11,7 @@ USING: alien ;
 : O_CREAT   HEX: 0200 ;
 : O_TRUNC   HEX: 0400 ;
                         
-: POLLIN     HEX: 0001 ;
-: POLLPRI    HEX: 0002 ;
-: POLLOUT    HEX: 0004 ;
+: FD_SETSIZE 1024 ;
 
 : SOL_SOCKET HEX: ffff ;
 : SO_REUSEADDR HEX: 4 ;
index 39f7d9547e8f4efeacbb3994aedb3442be46cbc2..04f86f9e0eb002f49679c407b923b53e5cee5be1 100644 (file)
@@ -11,12 +11,10 @@ USING: alien ;
 : O_CREAT   HEX: 0040 ;
 : O_TRUNC   HEX: 0200 ;
 
-: POLLIN     HEX: 0001 ;
-: POLLPRI    HEX: 0002 ;
-: POLLOUT    HEX: 0004 ;
-
 : SOL_SOCKET 1 ;
 
+: FD_SETSIZE 1024 ;
+
 : SO_REUSEADDR 2 ;
 : SO_OOBINLINE 10 ;
 : SO_SNDTIMEO HEX: 15 ;
index 45cc0fc34940c45b57efd2a675849a3de1562403..bfa5c557587bba660a47f94712ac3b79b7b55861 100644 (file)
@@ -11,9 +11,7 @@ USING: alien ;
 : O_CREAT   HEX: 0200 ;
 : O_TRUNC   HEX: 0400 ;
 
-: POLLIN     HEX: 0001 ;
-: POLLPRI    HEX: 0002 ;
-: POLLOUT    HEX: 0004 ;
+: FD_SETSIZE 1024 ;
 
 : SOL_SOCKET HEX: ffff ;
 : SO_REUSEADDR HEX: 4 ;
index 1284f0ea2b19cf01b06f8fdc0142b1847de35450..c1d3c84dd0bdb3f21c072fe1df7e96bdcd974a32 100644 (file)
@@ -7,43 +7,29 @@ USING: alien errors kernel math namespaces ;
 
 : EINPROGRESS 36 ;
 
-: errno ( -- n )
-    "int" f "factor_errno" [ ] alien-invoke ;
+LIBRARY: factor
+FUNCTION: int err_no ( ) ;
 
-: strerror ( n -- str )
-    "char*" "libc" "strerror" [ "int" ] alien-invoke ;
-
-: open ( path flags prot -- fd )
-    "int" "libc" "open" [ "char*" "int" "int" ] alien-invoke ;
-
-: close ( fd -- )
-    "void" "libc" "close" [ "int" ] alien-invoke ;
-
-: fcntl ( fd cmd arg -- n )
-    "int" "libc" "fcntl" [ "int" "int" "int" ] alien-invoke ;
-
-: read ( fd buf nbytes -- n )
-    "ssize_t" "libc" "read" [ "int" "ulong" "size_t" ] alien-invoke ;
-
-: write ( fd buf nbytes -- n )
-    "ssize_t" "libc" "write" [ "int" "ulong" "size_t" ] alien-invoke ;
-
-BEGIN-STRUCT: pollfd
-    FIELD: int fd
-    FIELD: short events
-    FIELD: short revents
-END-STRUCT
-
-: poll ( pollfds nfds timeout -- n )
-    "int" "libc" "poll" [ "pollfd*" "uint" "int" ] alien-invoke ;
+LIBRARY: libc
+FUNCTION: char* strerror ( int ) ;
+FUNCTION: int open ( char* path, int flags, int prot ) ;
+FUNCTION: void close ( int fd ) ;
+FUNCTION: int fcntl ( int fd, int cmd, int arg ) ;
+FUNCTION: ssize_t read ( int fd, ulong buf, size_t nbytes ) ;
+FUNCTION: ssize_t write ( int fd, ulong buf, size_t nbytes ) ;
 
 BEGIN-STRUCT: timeval
     FIELD: long sec
     FIELD: long usec
 END-STRUCT
 
-: select ( nfds readfds writefds exceptfds timeout -- n )
-    "int" "libc" "select" [ "int" "void*" "void*" "void*" "timeval*" ] alien-invoke ;
+: make-timeval ( ms -- timeval )
+    1000 /mod 1000 *
+    <timeval>
+    [ set-timeval-usec ] keep
+    [ set-timeval-sec ] keep ;
+
+FUNCTION: int select ( int nfds, void* readfds, void* writefds, void* exceptfds, timeval* timeout ) ;
 
 BEGIN-STRUCT: hostent
     FIELD: char* name
@@ -62,32 +48,13 @@ END-STRUCT
 : PF_INET AF_INET ;
 : SOCK_STREAM 1 ;
 
-: socket ( domain type protocol -- n )
-    "int" "libc" "socket" [ "int" "int" "int" ] alien-invoke ;
-
-: setsockopt ( s level optname optval optlen -- n )
-    "int" "libc" "setsockopt" [ "int" "int" "int" "void*" "socklen_t" ] alien-invoke ;
-
-: connect ( s name namelen -- n )
-    "int" "libc" "connect" [ "int" "sockaddr-in*" "socklen_t" ] alien-invoke ;
-
-: bind ( s sockaddr socklen -- n )
-    "int" "libc" "bind" [ "int" "sockaddr-in*" "socklen_t" ] alien-invoke ;
-
-: listen ( s backlog -- n )
-    "int" "libc" "listen" [ "int" "int" ] alien-invoke ;
-
-: accept ( s sockaddr socklen -- n )
-    "int" "libc" "accept" [ "int" "sockaddr-in*" "void*" ] alien-invoke ;
-
-: htonl ( n -- n )
-    "uint" "libc" "htonl" [ "uint" ] alien-invoke ;
-
-: htons ( n -- n )
-    "ushort" "libc" "htons" [ "ushort" ] alien-invoke ;
-
-: ntohl ( n -- n )
-    "uint" "libc" "ntohl" [ "uint" ] alien-invoke ;
-
-: ntohs ( n -- n )
-    "ushort" "libc" "ntohs" [ "ushort" ] alien-invoke ;
+FUNCTION: int socket ( int domain, int type, int protocol ) ;
+FUNCTION: int setsockopt ( int s, int level, int optname, void* optval, socklen_t optlen ) ;
+FUNCTION: int connect ( int s, sockaddr-in* name, socklen_t namelen ) ;
+FUNCTION: int bind ( int s, sockaddr-in* name, socklen_t namelen ) ;
+FUNCTION: int listen ( int s, int backlog ) ;
+FUNCTION: int accept ( int s, sockaddr-in* sockaddr, socklen_t* socklen ) ;
+FUNCTION: uint htonl ( uint n ) ;
+FUNCTION: ushort htons ( ushort n ) ;
+FUNCTION: uint ntohl ( uint n ) ;
+FUNCTION: ushort ntohs ( ushort n ) ;
index 642753ba4be33017e14bb3dd8ed97e4b71b46661..ffaf089b85d62d38279f584c8e21c01dfbe39211 100644 (file)
@@ -3,7 +3,7 @@
 /* This function is used by FFI I/O. Accessing the errno global is
 too troublesome... on some libc's its a funky macro that reads
 thread-local storage. */
-int factor_errno(void)
+int err_no(void)
 {
        return errno;
 }
index 72ddd77912de6c79a90f61ca1839db39c33ecaec..8918b56a46c0c295d96b656ad1895be7ea4f7de7 100644 (file)
@@ -1,4 +1,4 @@
-int factor_errno(void);
+int err_no(void);
 void init_c_io(void);
 void io_error(void);
 void primitive_fopen(void);