;;; -*- Mode:Lisp; Syntax:Common-lisp; Package: modlisp; Base:10 -*- (in-package #:modlisp) (defun make-socket-server (name function port &key wait format) (declare (ignore name)) (let ((listener (listen-to-inet-port :port port :reuse 1))) (values (sb-thread:make-thread (lambda () (start-socket-server listener function))) listener))) (defun start-socket-server (listener function) (handler-case (when (sb-sys:wait-until-fd-usable (sb-bsd-sockets:socket-file-descriptor listener) :input) (unwind-protect (loop (let* ((socket (sb-bsd-sockets:socket-accept listener)) (stream (sb-bsd-sockets:socket-make-stream socket :element-type 'base-char :input t :output t))) (sb-thread:make-thread #'(lambda () (apache-command-issuer stream function))))) (sb-unix:unix-close (sb-bsd-sockets:socket-file-descriptor listener)))) (sb-kernel::timeout (c) (format t "interrupted, time to die~%")))) (defun listen-to-inet-port (&key (port 0) (kind :stream) (reuse nil)) "Create, bind and listen to an inet socket on *:PORT. setsockopt SO_REUSEADDR if :reuse is not nil" (let ((socket (make-instance 'sb-bsd-sockets:inet-socket :type :stream :protocol :tcp))) (if reuse (setf (sb-bsd-sockets:sockopt-reuse-address socket) t)) (sb-bsd-sockets:socket-bind socket (sb-bsd-sockets:make-inet-address "0.0.0.0") port) (sb-bsd-sockets:socket-listen socket 15) socket))