[Openmcl-devel] *multiprocessing-socket-io*
R.Stoye
stoye at stoye.com
Thu Sep 16 15:01:54 PDT 2010
since i missed to post gb's answer, i'll repost the rest of the
conversation (per private mail) from 2008:
> If a thread is blocked in #_accept on a blocking socket in 1.1, I'm
> not sure that the thread can be killed by PROCESS-KILL. (Driving
> a wooden stake through the heart of the thread may work ...) This
> has to do with the fact that many blocking system calls are
> automatically
> restarted when the signal used by PROCESS-INTERRUPT is received.
>
> The good news about that is that code which calls those blocking
> system calls doesn't have to check to see if an "interrupted system
> call" error (#$EINTR) occurred and manually retry the call. The bad
> news is that when the handler for the interrupt signal is established
> with the SA_RESTART flag (as was the case in 1.1 and earlier), some
> system calls (including #_accept) will be automatically restarted
> and lisp won't regain control (and process the pending interrupt
> request) until #_accept returns "normally."
>
> When the socket's non-blocking, we don't generally block in
> #_accept (but instead wait interruptibly for input to be available);
> if PROCESS-KILL calls PROCESS-INTERRUPT to tell the thread to
> kill itself, the interruptible wait completes and as it's returning
> to lisp it handles the interrupt request and starts to kill itself.
>
> Just to see if I'm on the right track here, could you check to
> see if the thread is still around (quite possibly still blocked
> in #_accept) when the listener socket is blocking and PROCESS-KILL
> thinks that it's just killed the blocked thread ?
>
> If this (#_accept not getting interrupted) is the root of the
> problem, then the best thing to do in the short term is to make the
> socket non-blocking (by leaving *multiprocessing-socket-io*
> set to T). 1.2 doesn't make blocking system calls automatically
> restartable and is supposed to check each such system call for
> #$EINTR and manually restart it when that value is returned.
Am 10.03.2008 um 16:03 schrieb Gary Byers:
> Just to see if I'm on the right track here, could you check to
> see if the thread is still around (quite possibly still blocked
> in #_accept) when the listener socket is blocking and PROCESS-KILL
> thinks that it's just killed the blocked thread ?
yes, the thread is "still around":
the kill "proceeds" when a connection arives.
so i stay with *multiprocessing-socket-io* set to T
;; test:
;; simplest server waiting on 9001
(defun runaboo ()
(let ((theprocess (make-process "runaboo")))
(flet ((co-handler (client-stream)
(format T "~&Connection handler...")
(unwind-protect (print (read-line client-stream))
(close client-stream :abort t) )))
(process-preset theprocess
#'(lambda ()
(let ((server-socket (ccl:make-socket
:connect :passive
:local-port 9001
:reuse-address t
:external-format (make-external-format :character-
encoding :iso-8859-1 :line-termination :crlf)
))
(client-streams nil))
(unwind-protect
(progn (format t "~%entered unwind~%")
(loop
(format t "~%entered loop waiting for client~%")
(let* ((client-stream (ccl:accept-connection server-
socket :wait t)))
(push client-stream client-streams)
(format t "~%have client on stream ~s~%" client-stream)
(describe client-stream)
(unless client-streams
(error "no client???"))
(funcall #'co-handler client-stream)
(setf client-streams (remove client-stream client-streams) )))
(format t "~%after loop~%"))
(format t "~%closing server~%")
(format t "the clients are: ~s~%" client-streams)
(mapcar #'(lambda (s) (ignore-errors (close s :abort t)))
client-streams)
(format t "~%close server~%")
(close server-socket :abort t)
)))))
(process-enable theprocess)
theprocess))
? (setf ccl::*multiprocessing-socket-io* nil)
? (setf myboo (runaboo))
#<PROCESS runaboo(4) [Active] #x300041072C5D>
?
entered unwind
entered loop waiting for client
(ccl::process-kill myboo)
T
? (room t)
Approximately 29,753,344 bytes of memory can be allocated
before the next full GC is triggered.
Total Size Free Used
Lisp Heap: 47448064 (46336K) 29753344 (29056K) 17694720
(17280K)
Stacks: 18876320 (18434K) 18870640 (18428K) 5680 (6K)
Static: 1530144 (1494K) 0 (0K) 1530144
(1494K)
506834.750 MB reserved for heap expansion.
Initial(0)
cstack: 2504608 (2446K) 2504608 (2446K) 0 (0K)
vstack: 2371584 (2316K) 2371296 (2316K) 288 (0K)
tstack: 327680 (320K) 326928 (319K) 752 (1K)
listener(1)
cstack: 2506752 (2448K) 2506752 (2448K) 0 (0K)
vstack: 2166784 (2116K) 2165144 (2114K) 1640 (2K)
tstack: 2162688 (2112K) 2159632 (2109K) 3056 (3K)
runaboo(4)
cstack: 2506752 (2448K) 2506752 (2448K) 0 (0K)
vstack: 2166784 (2116K) 2166776 (2116K) 8 (0K)
tstack: 2162688 (2112K) 2162688 (2112K) 0 (0K)
NIL
?
;; in another Terminalwindow:
ps axMlwww | grep 6844
rs 6844 s006 0.0 S 31 0:00.16 0:00.20 501 6789
0 0 2715132 19176 - 0:00.99 /usr/local/src/ccl/dx86cl64
6844 0.0 S 31 0:00.01 0:00.00 501 6789
0 0 2715132 19176 - 0:00.99
6844 0.0 S 31 0:00.08 0:00.53 501 6789
0 0 2715132 19176 - 0:00.99
6844 0.0 S 31 0:00.00 0:00.00 501 6789
0 0 2715132 19176 - 0:00.99
;; so the runaboo really exists!
;; so does the listening socket:
[rs at macbook:~]$ netstat -an | grep 9001
tcp4 0 0 *.9001 *.*
LISTEN
;; now connect per telnet
telnet localhost 9001
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
;; meanwhile in openmcl:
?
closing server
the clients are: NIL
close server
;;; and after that the runaboo thread is gone, netstat reports nothing
on 9001
More information about the Openmcl-devel
mailing list