r5239: *** empty log message ***
authorKevin M. Rosenberg <kevin@rosenberg.net>
Sat, 5 Jul 2003 22:54:00 +0000 (22:54 +0000)
committerKevin M. Rosenberg <kevin@rosenberg.net>
Sat, 5 Jul 2003 22:54:00 +0000 (22:54 +0000)
base.lisp
impl-lispworks.lisp
modlisp.asd
server.lisp [new file with mode: 0644]
variables.lisp

index 6b63c4d06e1a24330cc690b311677130deb6ac27..649d82f254d23ad400c65f0aa455737016372763 100644 (file)
--- a/base.lisp
+++ b/base.lisp
@@ -7,49 +7,56 @@
 ;;;; Programmer:    Kevin M. Rosenberg
 ;;;; Date Started:  Dec 2002
 ;;;;
-;;;; $Id: base.lisp,v 1.3 2003/07/05 00:51:04 kevin Exp $
+;;;; $Id: base.lisp,v 1.4 2003/07/05 22:54:00 kevin Exp $
 ;;;; *************************************************************************
 
 (in-package #:modlisp)
 
+(defun destroy-process (process)
+  #+sbcl (sb-thread:destroy-thread process)
+  #+cmucl (mp:destroy-process process)
+  #+allegro (mp:process-kill process)
+  #+lispworks (mp:process-kill process)
+  )
 
-(let ((*listener-socket* nil)
-      (*listener-process* nil))
+(defun close-socket (sock)
+  (ignore-errors (close sock)))
 
-  (defun modlisp-start (&key (port +default-apache-port+)
-                            (function 'demo-apache-command-processor))
+
+(defun modlisp-start (&key (port +default-apache-port+)
+                          (function 'demo-apache-command-processor)
+                          (function-args nil))
+  (let ((listener (make-instance 'listener)))
     (handler-case
-       (make-socket-server (next-server-name) function port
-                           :format :text :wait nil)
+       (make-socket-server (next-server-name) function port listener
+                           :format :text :wait nil
+                           :function-args function-args)
       (error (e)
        (format t "~&Error while trying to start modlisp server~&  ~A" e)
        (decf *listener-count*)
-       nil)
+       (values nil nil))
       (:no-error (process socket)
-       (setq *listener-socket* socket)
-       (setq *listener-process* process)
-       process)))
-  
-  (defun modlisp-stop ()
-    (when *listener-process*
-      (format t "~&; killing modlisp server process ~A~%" *listener-process*)
-      (handler-case
-         (progn
-           #+sbcl (sb-thread:destroy-thread *listener-process*)
-           #+cmucl (mp:destroy-process *listener-process*)
-           #+allegro (mp:process-kill *listener-process*)
-           #+allegro (mp:process-allow-schedule)
-           #+lispworks (mp:process-kill *listener-process*))
-       (error (e)
-         (format t "~&Error while trying to kill modlisp server~&  ~A" e))
-       (:no-error (res)
-         (declare (ignore res))
-         (setq *listener-process* nil))))
-    (when *listener-socket*
-      (ignore-errors (close *listener-socket*))
-      (setq *listener-socket* nil)))
-  
- ) ;; closure
+       (setf (process listener) process)
+       (setf (socket listener) socket)
+       (push listener *active-listeners*)
+       listener))))
+    
+(defun modlisp-stop (listener)
+  (unless listener
+    (cmsg "listener is NIL in modlisp-stop")
+    (return-from modlisp-stop))
+  (dolist (worker (workers listener))
+    (close-socket (socket worker))
+    (destroy-process (process worker)))
+  (setf (workers listener) nil)
+  (with-slots (process socket) listener
+    (handler-case
+         (destroy-process process)
+      (error (e)
+       (format t "~&Error while trying to kill modlisp server~&  ~A" e)))
+    (when socket
+      (ignore-errors (close-socket socket))))
+  (setq *active-listeners* (remove listener *active-listeners*)))
     
 (defun next-server-name ()
   (format nil "modlisp-socket-server-~d" (incf *listener-count*))) 
       (*number-worker-requests* 0)
       (*close-apache-socket* t))
   
-  (defun apache-command-issuer (*apache-socket* processor-fun)
+  (defun apache-command-issuer (*apache-socket* processor-fun &rest args)
     "generates commands from apache, issues commands to processor-fun"
     (unwind-protect
         (progn
           (setq *number-worker-requests* 0)
           (do ((command (read-apache-command) (read-apache-command)))
               ((null command) 'done)
-            (funcall processor-fun command)
+            (apply processor-fun command args)
             (force-output *apache-socket*)
             (incf *number-worker-requests*)
             (incf *number-server-requests*)
index 86dfc57d5337b54cc1ab1c9736f8e7592241fc3b..15a9569573086edeb97fd858723575aec17e64ce 100644 (file)
@@ -2,8 +2,6 @@
 
 (in-package #:modlisp)
 
-(require "comm")
-
 (defvar *processor*)
 (let ((*processor* nil))
   
index 88d51fbaa8aedc6dd5ccedfb471b783865c4129f..a89d61ceaddf2daaaa2cb89acd289680c548fddd 100644 (file)
@@ -7,32 +7,36 @@
 ;;;; Programmer:    Kevin M. Rosenberg
 ;;;; Date Started:  Dec 2002
 ;;;;
-;;;; $Id: modlisp.asd,v 1.3 2003/07/05 00:51:04 kevin Exp $
+;;;; $Id: modlisp.asd,v 1.4 2003/07/05 22:54:00 kevin Exp $
 ;;;; *************************************************************************
 
-(defpackage #:modlisp-system (:use #:cl #:asdf))
-(in-package #:modlisp-system)
+(in-package #:cl-user)
 
 #+(and sbcl (not sb-thread))
 (error "This package requires the multitasking version of sbcl")
 
+(eval-when (:compile-toplevel :load-toplevel :execute)
+  #+sbcl (require :sb-bsd-sockets)
+  #+lispworks (require "comm")
+  #+allegro (require :socket))
+
+(defpackage #:modlisp-system (:use #:cl #:asdf))
+(in-package #:modlisp-system)
+
 #+(or allegro clisp cmu lispworks sbcl)
 (defsystem modlisp
-    :depends-on (#+sbcl :sb-bsd-sockets)
+    :depends-on (:kmrcl)
     :components
     ((:file "package")
      (:file "variables" :depends-on ("package"))
-     (:file #+allegro "impl-acl"
+     (:file "compat" :depends-on ("package"))
+     (:file #+(or allegro cmu sbcl) "server"
            #+clisp "impl-clisp"
-           #+cmu "impl-cmucl"
-           #+sbcl "impl-sbcl"
            #+lispworks "impl-lispworks"
-           :depends-on ("variables"))
+           :depends-on ("compat"))
      (:file "base"
-           :depends-on (#+allegro "impl-acl"
+           :depends-on (#+(or allegro cmu sbcl) "server"
                         #+clisp "impl-clisp"
-                        #+cmu "impl-cmucl"
-                        #+lispworks "impl-lispworks"
-                        #+sbcl "impl-sbcl"))
+                        #+lispworks "impl-lispworks"))
      (:file "utils" :depends-on ("base"))
      (:file "demo" :depends-on ("utils"))))
diff --git a/server.lisp b/server.lisp
new file mode 100644 (file)
index 0000000..26fc2d5
--- /dev/null
@@ -0,0 +1,58 @@
+;;; -*- Mode:Lisp; Syntax:Common-lisp; Package: modlisp; Base:10 -*-
+
+(in-package #:modlisp)
+
+
+(defun make-socket-server (name function port listener 
+                          &key wait (format :text) function-args)
+  (let* ((passive-socket (create-inet-listener port :format format))
+        (proc (make-process name
+                            #'(lambda ()
+                                (start-socket-server
+                                 passive-socket function listener
+                                 :wait wait 
+                                 :function-args function-args)))))
+    (values proc passive-socket)))
+
+
+(defmethod initialize-instance :after
+          ((self worker) &key listener socket func name function-args
+           &allow-other-keys)
+  (unless socket
+    (error "socket not provided to modlisp-worker"))
+  (setf (slot-value self 'listener) listener)
+  (setf (slot-value self 'func) func)
+  (setf (slot-value self 'function-args) function-args)
+  (setf (slot-value self 'thread-fun)
+    #'(lambda ()
+       (unwind-protect
+           (handler-case
+               (apply #'apache-command-issuer socket func function-args)
+             (error (e)
+               (cmsg "Error ~A [~A]" e name)
+               ;;(error e)
+               ))
+         (progn
+           (errorset (close-active-socket socket) nil)
+           (cmsg-c :threads "~A ended" name)
+           (setf (workers listener)
+             (remove self (workers listener))))))))
+
+(defun start-socket-server (passive-socket function listener 
+                           &key wait function-args)
+  (unwind-protect
+      (loop 
+       (let ((connection (accept-tcp-connection passive-socket)))
+         (if wait
+             (unwind-protect
+                 (funcall connection function)
+               (errorset (close connection) nil))
+           (let ((worker (make-instance 'worker :listener listener
+                                        :func function
+                                        :function-args function-args
+                                        :name (next-worker-name)
+                                        :socket connection)))
+             (setf (process worker)
+               (make-process (name worker) (thread-fun worker)))
+             (push worker (workers listener))))))
+    (errorset (close-passive-socket passive-socket) nil)))
index 20239a17601fde28fe0d41a9c3c3a974186a4872..d9f4f1ee87e53fc02e58130e9eb5e69591ca0611 100644 (file)
@@ -7,7 +7,7 @@
 ;;;; Programmer:    Kevin M. Rosenberg
 ;;;; Date Started:  Dec 2002
 ;;;;
-;;;; $Id: variables.lisp,v 1.3 2003/07/05 01:34:42 kevin Exp $
+;;;; $Id: variables.lisp,v 1.4 2003/07/05 22:54:00 kevin Exp $
 ;;;; *************************************************************************
 
 (in-package #:modlisp)
 (defvar *apache-socket* nil
   "the socket stream to apache")
 
-(defvar *listener-socket*
-  "Socket for the listener")
-
-(defvar *listener-process* nil
-  "Process for the listener")
-
 (defvar *number-server-requests* 0)
 (defvar *number-worker-requests* 0)
 (defvar *close-apache-socket* t)
 
-
-
+(defclass listener ()
+  ((process :initarg process :accessor process)
+   (socket :initarg socket :accessor socket)
+   (workers :initform nil :accessor workers
+           :documentation "list of worker threads")))
+
+(defvar *active-listeners* nil
+    "List of active listeners")
+
+(defclass worker ()
+  ((listener :initarg :listener :accessor listener :initform nil)
+   (name :initarg :name :accessor name :initform nil)
+   (func :initarg :func :accessor func :initform nil)
+   (function-args :initarg :function-args :accessor function-args
+                 :initform nil)
+   (socket :initarg :socket :accessor socket :initform nil)
+   (thread-fun :initarg :thread-fun :accessor thread-fun :initform nil)
+   (process :initarg :process :accessor process :initform nil)))
+
+