| 1 | (defpackage :hemlock.wire
|
|---|
| 2 | (:use :common-lisp))
|
|---|
| 3 |
|
|---|
| 4 | (in-package :hemlock.wire)
|
|---|
| 5 |
|
|---|
| 6 | (defun ext-create-inet-listener (port)
|
|---|
| 7 | #+CMU
|
|---|
| 8 | (ext:create-inet-listener port)
|
|---|
| 9 | #+EXCL
|
|---|
| 10 | (socket:make-socket :connect :passive
|
|---|
| 11 | :local-port port
|
|---|
| 12 | :format :text)
|
|---|
| 13 | #+CLISP
|
|---|
| 14 | (socket:socket-server port)
|
|---|
| 15 | #+SBCL
|
|---|
| 16 | (let ((socket (make-instance 'sb-bsd-sockets:inet-socket
|
|---|
| 17 | :type :stream
|
|---|
| 18 | :protocol (sb-bsd-sockets:get-protocol-by-name "tcp"))))
|
|---|
| 19 | (sb-bsd-sockets:socket-bind socket (sb-bsd-sockets:make-inet-address "0.0.0.0") port)
|
|---|
| 20 | (sb-bsd-sockets:socket-listen socket 2)
|
|---|
| 21 | socket)
|
|---|
| 22 | #-(OR CMU EXCL CLISP SBCL)
|
|---|
| 23 | #.(error "Configure"))
|
|---|
| 24 |
|
|---|
| 25 | (defun ext-accept-tcp-connection (socket)
|
|---|
| 26 | #+CMU (ext:accept-tcp-connection socket)
|
|---|
| 27 | #+EXCL
|
|---|
| 28 | (values
|
|---|
| 29 | (socket:accept-connection socket :wait t)
|
|---|
| 30 | (socket:remote-host socket))
|
|---|
| 31 | #+CLISP
|
|---|
| 32 | (let ((stream (socket:socket-accept socket)))
|
|---|
| 33 | #+NIL (setf (stream-element-type stream) '(unsigned-byte 8))
|
|---|
| 34 | (values
|
|---|
| 35 | stream
|
|---|
| 36 | (multiple-value-list (socket:socket-stream-peer stream))))
|
|---|
| 37 | #+SBCL
|
|---|
| 38 | (multiple-value-bind (socket peer-host peer-port)
|
|---|
| 39 | (sb-bsd-sockets:socket-accept socket)
|
|---|
| 40 | (values (sb-bsd-sockets:socket-make-stream socket :element-type 'character :input t :output t)
|
|---|
| 41 | peer-host))
|
|---|
| 42 | #-(OR CMU EXCL CLISP SBCL)
|
|---|
| 43 | #.(error "Configure")
|
|---|
| 44 | )
|
|---|
| 45 |
|
|---|
| 46 | (defun ext-connect-to-inet-socket (host port)
|
|---|
| 47 | #+CMU (ext:connect-to-inet-socket host port)
|
|---|
| 48 | #+EXCL
|
|---|
| 49 | (progn
|
|---|
| 50 | #+(and allegro-version>= (version>= 5))
|
|---|
| 51 | (socket:make-socket :remote-host host
|
|---|
| 52 | :remote-port port
|
|---|
| 53 | :format :text)
|
|---|
| 54 | #-(and allegro-version>= (version>= 5))
|
|---|
| 55 | (ipc:open-network-stream
|
|---|
| 56 | :host host :port port
|
|---|
| 57 | :element-type 'character
|
|---|
| 58 | ;; :class EXCL::BIDIRECTIONAL-BINARY-SOCKET-STREAM
|
|---|
| 59 | ))
|
|---|
| 60 | #+SBCL
|
|---|
| 61 | (sb-bsd-sockets:socket-make-stream
|
|---|
| 62 | (let ((host (car (sb-bsd-sockets:host-ent-addresses
|
|---|
| 63 | (sb-bsd-sockets:get-host-by-name host)))))
|
|---|
| 64 | (when host
|
|---|
| 65 | (let ((s (make-instance 'sb-bsd-sockets:inet-socket
|
|---|
| 66 | :type :stream :protocol :tcp)))
|
|---|
| 67 | (sb-bsd-sockets:socket-connect s host port)
|
|---|
| 68 | s)))
|
|---|
| 69 | :element-type 'character ;(unsigned-byte 8)
|
|---|
| 70 | :input t :output t)
|
|---|
| 71 | #+CLISP
|
|---|
| 72 | (socket:socket-connect port host)
|
|---|
| 73 | #-(OR CMU EXCL CLISP SBCL)
|
|---|
| 74 | #.(error "Configure"))
|
|---|
| 75 |
|
|---|
| 76 | (defun ext-close-socket (socket)
|
|---|
| 77 | #+CMU (ext:close-socket socket)
|
|---|
| 78 | #+EXCL (close socket)
|
|---|
| 79 | #+CLISP (socket:socket-server-close socket)
|
|---|
| 80 | #+SBCL (sb-bsd-sockets:socket-close socket)
|
|---|
| 81 | #-(OR CMU EXCL CLISP SBCL)
|
|---|
| 82 | #.(error "Configure"))
|
|---|
| 83 |
|
|---|
| 84 | (defun ext-close-connection (connection)
|
|---|
| 85 | #+CMU (ext:close-socket connection)
|
|---|
| 86 | #+EXCL (close connection)
|
|---|
| 87 | #+CLISP (close connection)
|
|---|
| 88 | #+SBCL (close connection)
|
|---|
| 89 | #-(OR CMU EXCL CLISP SBCL)
|
|---|
| 90 | #.(error "Configure"))
|
|---|
| 91 |
|
|---|
| 92 | (defun unix-gethostid ()
|
|---|
| 93 | #.(or
|
|---|
| 94 | #+CMU '(unix:unix-gethostid)
|
|---|
| 95 | 398792))
|
|---|
| 96 |
|
|---|
| 97 | (defun unix-getpid ()
|
|---|
| 98 | #.(or
|
|---|
| 99 | #+CMU '(unix:unix-getpid)
|
|---|
| 100 | #+SBCL '(sb-unix:unix-getpid)
|
|---|
| 101 | #+ACL '(excl::getpid)
|
|---|
| 102 | #+CLISP '(system::program-id)))
|
|---|
| 103 |
|
|---|
| 104 | #+(OR CLISP)
|
|---|
| 105 | (eval-when (compile load eval)
|
|---|
| 106 | (pushnew :hemlock.serve-event *features*) )
|
|---|
| 107 |
|
|---|
| 108 | #-:hemlock.serve-event
|
|---|
| 109 | (defun make-process (function &key name)
|
|---|
| 110 | #+CMU (mp:make-process function :name name)
|
|---|
| 111 | #+EXCL (mp:process-run-function name function)
|
|---|
| 112 | #+SBCL (sb-thread:make-thread function)
|
|---|
| 113 | #-(OR CMU EXCL SBCL)
|
|---|
| 114 | #.(error "Configure"))
|
|---|
| 115 |
|
|---|
| 116 | #+:hemlock.serve-event
|
|---|
| 117 | (progn
|
|---|
| 118 |
|
|---|
| 119 | (defstruct handler
|
|---|
| 120 | predicate
|
|---|
| 121 | function)
|
|---|
| 122 |
|
|---|
| 123 | (defvar *event-handlers* nil)
|
|---|
| 124 |
|
|---|
| 125 | ;; Sigh. CLISP barfs on (typep (ext-create-inet-listener 8981) 'SOCKET:SOCKET-SERVER)
|
|---|
| 126 | ;; Bad!
|
|---|
| 127 |
|
|---|
| 128 | (defun add-fd-handler (fd direction handler-function)
|
|---|
| 129 | (let (handler)
|
|---|
| 130 | (setf handler
|
|---|
| 131 | (make-handler
|
|---|
| 132 | :predicate
|
|---|
| 133 | (cond ((eql 'socket:socket-server
|
|---|
| 134 | (type-of fd))
|
|---|
| 135 | (lambda () (socket:socket-wait fd 0)))
|
|---|
| 136 | ((typep fd 'xlib:display)
|
|---|
| 137 | (lambda ()
|
|---|
| 138 | (xlib:display-force-output fd)
|
|---|
| 139 | (xlib:event-listen fd)))
|
|---|
| 140 | (t
|
|---|
| 141 | (lambda ()
|
|---|
| 142 | (cond ((open-stream-p fd)
|
|---|
| 143 | (let ((c (read-char-no-hang fd nil :eof)))
|
|---|
| 144 | #+NIL (progn (print `(read-char-no-hang ,fd -> ,c)) (finish-output))
|
|---|
| 145 | (if (characterp c) (unread-char c fd))
|
|---|
| 146 | c))
|
|---|
| 147 | (t
|
|---|
| 148 | (setf *event-handlers* (delete handler *event-handlers*))
|
|---|
| 149 | nil)))))
|
|---|
| 150 | :function
|
|---|
| 151 | (lambda () (funcall handler-function fd))))
|
|---|
| 152 | (push handler *event-handlers*)
|
|---|
| 153 | handler))
|
|---|
| 154 |
|
|---|
| 155 | (defun remove-fd-handler (handler)
|
|---|
| 156 | (setf *event-handlers*
|
|---|
| 157 | (delete handler *event-handlers*)))
|
|---|
| 158 |
|
|---|
| 159 | (defun serve-all-events ()
|
|---|
| 160 | (loop
|
|---|
| 161 | (let ((handler (find-if #'funcall *event-handlers* :key #'handler-predicate)))
|
|---|
| 162 | (cond (handler
|
|---|
| 163 | (funcall (handler-function handler))
|
|---|
| 164 | (return))
|
|---|
| 165 | (t
|
|---|
| 166 | (sleep .01))))))
|
|---|
| 167 |
|
|---|
| 168 | (defun serve-event (&optional timeout)
|
|---|
| 169 | (let ((waited 0))
|
|---|
| 170 | (loop
|
|---|
| 171 | (let ((handler (find-if #'funcall *event-handlers* :key #'handler-predicate)))
|
|---|
| 172 | (cond (handler
|
|---|
| 173 | (funcall (handler-function handler))
|
|---|
| 174 | (return t))
|
|---|
| 175 | ((>= waited timeout)
|
|---|
| 176 | (return nil))
|
|---|
| 177 | (t
|
|---|
| 178 | (incf waited .01)
|
|---|
| 179 | (sleep .01)))))))
|
|---|
| 180 | )
|
|---|
| 181 |
|
|---|
| 182 | ||#
|
|---|