mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-07-03 16:20:39 +02:00
add ability to wake up the poll() in http.scm
* module/web/server/http.scm (make-waker, flush-wake-port): New functions, to wake up a poll(). (http-open): Add a wakeup port to the poll set. (http-read): Handle the wakeup port specially.
This commit is contained in:
parent
5f54be9b3d
commit
31a04ee239
1 changed files with 31 additions and 4 deletions
|
@ -30,6 +30,7 @@
|
||||||
(define-module (web server http)
|
(define-module (web server http)
|
||||||
#:use-module ((srfi srfi-1) #:select (fold))
|
#:use-module ((srfi srfi-1) #:select (fold))
|
||||||
#:use-module (srfi srfi-9)
|
#:use-module (srfi srfi-9)
|
||||||
|
#:use-module (ice-9 binary-ports)
|
||||||
#:use-module (rnrs bytevectors)
|
#:use-module (rnrs bytevectors)
|
||||||
#:use-module (web request)
|
#:use-module (web request)
|
||||||
#:use-module (web response)
|
#:use-module (web response)
|
||||||
|
@ -43,12 +44,31 @@
|
||||||
(bind sock family addr port)
|
(bind sock family addr port)
|
||||||
sock))
|
sock))
|
||||||
|
|
||||||
|
(define (make-waker)
|
||||||
|
(let ((wakeup (socketpair AF_UNIX SOCK_STREAM 0)))
|
||||||
|
(fcntl (car wakeup) F_SETFL O_NONBLOCK)
|
||||||
|
(fcntl (cdr wakeup) F_SETFL O_NONBLOCK)
|
||||||
|
#;
|
||||||
|
(if (defined? 'O_CLOEXEC)
|
||||||
|
(begin
|
||||||
|
;; FIXME: currently it's not defined...
|
||||||
|
(fcntl (car wakeup) F_SETFD O_CLOEXEC)
|
||||||
|
(fcntl (cdr wakeup) F_SETFD O_CLOEXEC)))
|
||||||
|
(values (lambda () (put-u8 (car wakeup) 0))
|
||||||
|
(cdr wakeup))))
|
||||||
|
|
||||||
|
(define flush-wake-port
|
||||||
|
;; FIXME: need a bytevector-get-n! that understands nonblocking ports.
|
||||||
|
(lambda (port)
|
||||||
|
(get-u8 port)))
|
||||||
|
|
||||||
(define-record-type <http-server>
|
(define-record-type <http-server>
|
||||||
(make-http-server socket poll-idx poll-set)
|
(make-http-server socket poll-idx poll-set wake-thunk)
|
||||||
http-server?
|
http-server?
|
||||||
(socket http-socket)
|
(socket http-socket)
|
||||||
(poll-idx http-poll-idx set-http-poll-idx!)
|
(poll-idx http-poll-idx set-http-poll-idx!)
|
||||||
(poll-set http-poll-set))
|
(poll-set http-poll-set)
|
||||||
|
(wake-thunk http-wake-thunk))
|
||||||
|
|
||||||
(define *error-events* (logior POLLHUP POLLERR))
|
(define *error-events* (logior POLLHUP POLLERR))
|
||||||
(define *read-events* POLLIN)
|
(define *read-events* POLLIN)
|
||||||
|
@ -66,8 +86,11 @@
|
||||||
(listen socket 128)
|
(listen socket 128)
|
||||||
(sigaction SIGPIPE SIG_IGN)
|
(sigaction SIGPIPE SIG_IGN)
|
||||||
(let ((poll-set (make-empty-poll-set)))
|
(let ((poll-set (make-empty-poll-set)))
|
||||||
|
(call-with-values make-waker
|
||||||
|
(lambda (wake-thunk wake-port)
|
||||||
(poll-set-add! poll-set socket *events*)
|
(poll-set-add! poll-set socket *events*)
|
||||||
(make-http-server socket 0 poll-set)))
|
(poll-set-add! poll-set wake-port *read-events*)
|
||||||
|
(make-http-server socket 0 poll-set wake-thunk)))))
|
||||||
|
|
||||||
(define (bad-request port)
|
(define (bad-request port)
|
||||||
(write-response (build-response #:version '(1 . 0) #:code 400
|
(write-response (build-response #:version '(1 . 0) #:code 400
|
||||||
|
@ -106,6 +129,10 @@
|
||||||
((zero? revents)
|
((zero? revents)
|
||||||
;; Nothing on this port.
|
;; Nothing on this port.
|
||||||
(lp (1- idx)))
|
(lp (1- idx)))
|
||||||
|
((= idx 1)
|
||||||
|
;; The wakeup socket.
|
||||||
|
(flush-wake-port (poll-set-port poll-set idx))
|
||||||
|
(lp (1- idx)))
|
||||||
;; Otherwise, a client socket with some activity on
|
;; Otherwise, a client socket with some activity on
|
||||||
;; it. Remove it from the poll set.
|
;; it. Remove it from the poll set.
|
||||||
(else
|
(else
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue