--- ../chicken-core/tcp.scm 2013-03-21 18:11:26.000000000 +0100 +++ tcp.scm 2013-03-21 18:52:48.000000000 +0100 @@ -50,6 +50,7 @@ # ifndef EINPROGRESS # define EINPROGRESS 0 # endif +# define EAGAIN 0 # define typecorrect_getsockopt(socket, level, optname, optval, optlen) \ getsockopt(socket, level, optname, (char *)optval, optlen) #else @@ -183,27 +184,8 @@ (define ##net#select (foreign-lambda* int ((int fd)) - "fd_set in; - struct timeval tm; - int rv; - FD_ZERO(&in); - FD_SET(fd, &in); - tm.tv_sec = tm.tv_usec = 0; - rv = select(fd + 1, &in, NULL, NULL, &tm); - if(rv > 0) { rv = FD_ISSET(fd, &in) ? 1 : 0; } - C_return(rv);") ) - -(define ##net#select-write - (foreign-lambda* int ((int fd)) - "fd_set out; - struct timeval tm; - int rv; - FD_ZERO(&out); - FD_SET(fd, &out); - tm.tv_sec = tm.tv_usec = 0; - rv = select(fd + 1, NULL, &out, NULL, &tm); - if(rv > 0) { rv = FD_ISSET(fd, &out) ? 1 : 0; } - C_return(rv);") ) + "struct pollfd ps; ps.fd = fd; ps.events = POLLIN|POLLPRI;" + "C_return(poll(&ps, 1, 0));")) (define ##net#gethostaddr (foreign-lambda* bool ((scheme-pointer saddr) (c-string host) (unsigned-short port)) @@ -216,13 +198,6 @@ "addr->sin_addr = *((struct in_addr *)he->h_addr);" "C_return(1);") ) -(define (yield) - (##sys#call-with-current-continuation - (lambda (return) - (let ((ct ##sys#current-thread)) - (##sys#setslot ct 1 (lambda () (return (##core#undefined)))) - (##sys#schedule) ) ) ) ) - (define-syntax network-error (syntax-rules () ((_ loc msg . args) @@ -354,8 +329,7 @@ (##sys#thread-block-for-timeout! ##sys#current-thread (+ (current-milliseconds) tmr) ) ) - (##sys#thread-block-for-i/o! ##sys#current-thread fd #:input) - (yield) + (thread-wait-for-i/o! fd #:input) (when (##sys#slot ##sys#current-thread 13) (##sys#signal-hook #:network-timeout-error @@ -456,8 +430,7 @@ (##sys#thread-block-for-timeout! ##sys#current-thread (+ (current-milliseconds) tmw) ) ) - (##sys#thread-block-for-i/o! ##sys#current-thread fd #:output) - (yield) + (thread-wait-for-i/o! fd #:output) (when (##sys#slot ##sys#current-thread 13) (##sys#signal-hook #:network-timeout-error @@ -507,27 +480,24 @@ (##sys#check-structure tcpl 'tcp-listener) (let ((fd (##sys#slot tcpl 1)) (tma (tcp-accept-timeout))) + (if tma + (##sys#thread-block-for-timeout! + ##sys#current-thread + (+ (current-milliseconds) tma) ) ) (let loop () - (if (eq? 1 (##net#select fd)) - (let ((fd (##net#accept fd #f #f))) - (cond ((not (eq? -1 fd)) (##net#io-ports fd)) - ((eq? errno _eintr) - (##sys#dispatch-interrupt loop)) - (else - (network-error 'tcp-accept "could not accept from listener" tcpl)))) - (begin - (when tma - (##sys#thread-block-for-timeout! - ##sys#current-thread - (+ (current-milliseconds) tma) ) ) - (##sys#thread-block-for-i/o! ##sys#current-thread fd #:input) - (yield) - (when (##sys#slot ##sys#current-thread 13) - (##sys#signal-hook - #:network-timeout-error - 'tcp-accept - "accept operation timed out" tma fd) ) - (loop) ) ) ) ) ) + (##sys#thread-block-for-i/o! ##sys#current-thread fd #:input) + (##sys#thread-yield!) + (if (##sys#slot ##sys#current-thread 13) + (##sys#signal-hook + #:network-timeout-error + 'tcp-accept + "accept operation timed out" tma fd) ) + (let ((fd (##net#accept fd #f #f))) + (cond ((not (eq? -1 fd)) (##net#io-ports fd)) + ((eq? errno _eintr) + (##sys#dispatch-interrupt loop)) + (else + (network-error 'tcp-accept "could not accept from listener" tcpl)))) ) ) ) (define (tcp-accept-ready? tcpl) (##sys#check-structure tcpl 'tcp-listener 'tcp-accept-ready?) @@ -563,32 +533,18 @@ (unless (##net#make-nonblocking s) (network-error 'tcp-connect "fcntl() failed") ) (let loop () - (when (eq? -1 (##net#connect s addr _sockaddr_in_size)) - (cond ((eq? errno _einprogress) - (let loop2 () - (let ((f (##net#select-write s))) - (when (eq? f -1) - (##net#close s) - (network-error 'tcp-connect "cannot connect to socket" host port)) - (unless (eq? f 1) - (when tmc - (##sys#thread-block-for-timeout! - ##sys#current-thread - (+ (current-milliseconds) tmc) ) ) - (##sys#thread-block-for-i/o! ##sys#current-thread s #:all) - (yield) - (when (##sys#slot ##sys#current-thread 13) - (##net#close s) - (##sys#signal-hook - #:network-timeout-error - 'tcp-connect - "connect operation timed out" tmc s) ) - (loop2) ) ) )) + (if (eq? -1 (connect s addr _sockaddr_in_size)) + (cond ((eq? errno _einprogress) + (if tmc + (##sys#thread-block-for-timeout! + ##sys#current-thread + (+ (current-milliseconds) tmc) ) ) + (thread-wait-for-i/o! s #:all)) ((eq? errno _eintr) (##sys#dispatch-interrupt loop)) (else (##net#close s) - (network-error 'tcp-connect "cannot connect to socket" host port))))) + (network-error 'tcp-connect "cannot connect to socket" host port)) ))) (let ((err (get-socket-error s))) (cond ((fx= err -1) (##net#close s)