Hello,

I just discovered, by accident, another way CMUCL's GC went into an infinite loop. I am not sure whether its related to the previous problem (1K socket connections). But here goes (Note: I am using CMUCL 19c, TBNL) -

Recently I added a piece of code to our website which makes an HTTP post request to another machine. However, the IP address of that machine was *not* accessible at the time. And what happened was that our website became unresponsive. When I connected to the running lisp and tried to evaluate any form, nothing was returned. Then I pressed Ctrl-C, and got the following message in the debugger, and GC went into an infinite loop:

Interrupted at #xFFFFE40E.
  [Condition of type SIMPLE-CONDITION]

Restarts:
 0: [CONTINUE] Return from BREAK.
 1: [DESTROY ] Destroy the process

Debug  (type H for help)

(UNIX::SIGINT-HANDLER #<unused-arg> #<unused-arg> #.(SYSTEM:INT-SAP #x3FFFC8D8))
Source: Error finding source:
Error in function DEBUG::GET-FILE-TOP-LEVEL-FORM: Source file no longer exists:
 target:code/signal.lisp.
0]
; [GC threshold exceeded with 12,532,272 bytes in use.  Commencing GC.]
; [GC completed with 685,144 bytes retained and 11,847,128 bytes freed.]
; [GC will next occur when at least 12,685,144 bytes are in use.]
; [GC threshold exceeded with 12,698,704 bytes in use.  Commencing GC.]
; [GC completed with 695,208 bytes retained and 12,003,496 bytes freed.]
; [GC will next occur when at least 12,695,208 bytes are in use.]
; [GC threshold exceeded with 12,708,768 bytes in use.  Commencing GC.]
; [GC completed with 713,464 bytes retained and 11,995,304 bytes freed.]
.
.
.

On entering option 1, I can usually get out of this loop, but then again no Lisp forms were evaluated. I used the following modified version of trivial-http:http-post to send the request -

(defun http-post (url content-type content &key (timeout 120))
 (let* ((host (url-host url))
        (port (url-port url))
        (stream (open-stream host port)))
   (unwind-protect
(mp:with-timeout (timeout (error "Timeout occurred. Current timeout value - ~a sec" timeout)) (format stream "POST ~A HTTP/1.0~AHost: ~A~AUser-Agent: Trivial HTTP for Common Lisp~AContent-Type: ~A~AContent-Length: ~D~A~A~A" url +crlf+ host +crlf+ +crlf+ content-type +crlf+ (length content) +crlf+ +crlf+ content)
          (force-output stream)
          (response-read-code stream)
          (response-read-headers stream)
          (with-output-to-string (s)
            (loop for line = (copy-seq (read-line stream nil nil))
               while line do (write-string line s))))
     (when stream
       (close stream)))))

I am using it this way - I create a new process (using mp:make-process), and call http-post from that process -

(defun send-other-request (content)
 (mp:make-process (lambda ()
(handler-case (thttp:http-post *remote-listener-url* "application/x-www-form-urlencoded" content)
                      (error () nil)))))

send-other-request is called by one of the (URL) handler functions in TBNL.

Everything is ok when the remote machine is accessible. It only happens when its not. Any pointers on why its happening?

Thanks,
Chaitanya

Reply via email to