[slime-cvs] CVS update: slime/swank-sbcl.lisp
Luke Gorrie
lgorrie at common-lisp.net
Mon Jan 12 02:14:03 UTC 2004
Update of /project/slime/cvsroot/slime
In directory common-lisp.net:/tmp/cvs-serv21620
Modified Files:
swank-sbcl.lisp
Log Message:
Implemented new server interface.
Date: Sun Jan 11 21:14:03 2004
Author: lgorrie
Index: slime/swank-sbcl.lisp
diff -u slime/swank-sbcl.lisp:1.45 slime/swank-sbcl.lisp:1.46
--- slime/swank-sbcl.lisp:1.45 Fri Jan 2 13:23:14 2004
+++ slime/swank-sbcl.lisp Sun Jan 11 21:14:03 2004
@@ -61,6 +61,43 @@
;;; TCP Server
+
+(defmethod create-socket-server (init-fn &key announce-fn (port 0)
+ (accept-background t)
+ (handle-background t)
+ (loop t)
+ (reuse-address t))
+ (let ((socket (open-listener port reuse-address)))
+ (funcall announce-fn (local-tcp-port socket))
+ (setup-socket-accept socket init-fn accept-background handle-background loop)))
+
+(defun setup-socket-accept (socket init-fn accept-background handle-background loop)
+ (flet ((accept-client (&optional fd)
+ (declare (ignore fd))
+ (accept-one-client socket init-fn handle-background (not loop))))
+ (cond (accept-background (add-input-handler socket #'accept-client))
+ (loop (loop (accept-client)))
+ (t (accept-client)))))
+
+(defun accept-one-client (server-socket init-fn background close)
+ (let* ((client-socket (accept server-socket))
+ (socket-stream (make-socket-io-stream client-socket))
+ (handler-fn (funcall init-fn socket-stream)))
+ (when close
+ (sb-sys:invalidate-descriptor (sb-bsd-sockets:socket-file-descriptor
+ server-socket))
+ (sb-bsd-sockets:socket-close server-socket))
+ (if background
+ (add-input-handler client-socket
+ (lambda (fdes)
+ (declare (ignore fdes))
+ (funcall handler-fn)))
+ (loop (funcall handler-fn)))))
+
+(defun add-input-handler (socket handler-fn)
+ (sb-sys:add-fd-handler (sb-bsd-sockets:socket-file-descriptor socket)
+ :input handler-fn))
+
(defun open-listener (port reuse-address)
(let ((socket (make-instance 'sb-bsd-sockets:inet-socket
:type :stream
@@ -72,70 +109,29 @@
(sb-bsd-sockets:socket-listen socket 5)
socket))
+(defun local-tcp-port (socket)
+ (nth-value 1 (sb-bsd-sockets:socket-name socket)))
+
+(defun make-socket-io-stream (socket)
+ (sb-bsd-sockets:socket-make-stream socket
+ :output t
+ :input t
+ :element-type 'base-char))
+
+
(defun accept (socket)
"Like socket-accept, but retry on EAGAIN."
(loop (handler-case
(return (sb-bsd-sockets:socket-accept socket))
(sb-bsd-sockets:interrupted-error ()))))
-(defun create-swank-server (port &key (reuse-address t)
- (announce #'simple-announce-function))
- "Create a SWANK TCP server."
- (let ((socket (open-listener port reuse-address)))
- (sb-sys:add-fd-handler
- (sb-bsd-sockets:socket-file-descriptor socket)
- :input (lambda (fd)
- (declare (ignore fd))
- (accept-connection socket)))
- (funcall announce (nth-value 1 (sb-bsd-sockets:socket-name socket)))))
-
-(defun open-stream-to-emacs ()
- (let* ((server-socket (open-listener 0 t))
- (port (nth-value 1 (sb-bsd-sockets:socket-name server-socket))))
- (unwind-protect
- (progn
- (eval-in-emacs `(slime-open-stream-to-lisp ,port))
- (let ((socket (accept server-socket)))
- (sb-bsd-sockets:socket-make-stream
- socket :output t :element-type 'base-char)))
- (sb-bsd-sockets:socket-close server-socket))))
-
-(defvar *use-dedicated-output-stream* t)
-
-(defun accept-connection (server-socket)
- "Accept one Swank TCP connection on SERVER-SOCKET and then close it."
- (let* ((socket (accept server-socket))
- (stream (sb-bsd-sockets:socket-make-stream
- socket :input t :output t :element-type 'base-char))
- (out (if *use-dedicated-output-stream*
- (let ((*emacs-io* stream)) (open-stream-to-emacs))
- (make-instance 'slime-output-stream)))
- (in (make-instance 'slime-input-stream))
- (io (make-two-way-stream in out)))
- ;; we're being called from a serve-event handler: remove it now
- ;; because socket-close doesn't (in 0.8.6 anyway) do it for us
- (sb-sys:invalidate-descriptor (sb-bsd-sockets:socket-file-descriptor
- server-socket))
- (sb-bsd-sockets:socket-close server-socket)
- (sb-sys:add-fd-handler
- (sb-bsd-sockets:socket-file-descriptor socket)
- :input (lambda (fd)
- (declare (ignore fd))
- (serve-request stream out in io)))))
-
-
-(defun serve-request (*emacs-io* *slime-output* *slime-input* *slime-io*)
- "Read and process a request from a SWANK client.
-The request is read from the socket as a sexp and then evaluated."
- (catch 'slime-toplevel
- (handler-case (read-from-emacs)
- (slime-read-error (e)
- (when *swank-debug-p*
- (format *debug-io* "~&;; Connection to Emacs lost.~%;; [~A]~%" e))
- (sb-sys:invalidate-descriptor (sb-impl::fd-stream-fd *emacs-io*))
- (close *emacs-io* :abort t)
- (when *use-dedicated-output-stream*
- (close *slime-output* :abort t))))))
+(defmethod make-fn-streams (input-fn output-fn)
+ (let* ((output (make-instance 'slime-output-stream
+ :output-fn output-fn))
+ (input (make-instance 'slime-input-stream
+ :input-fn input-fn
+ :output-stream output)))
+ (values input output)))
;;; Utilities
More information about the slime-cvs
mailing list