Ticket #1050 (closed defect: fixed)

Opened 21 months ago

Last modified 21 months ago

Bad file descriptor error in accept or bind or listen

Reported by: jlawrence Owned by:
Priority: normal Milestone:
Component: other Version: trunk
Keywords: Cc:

Description

(defun run-server (host port out)
  (with-open-stream (server (ccl:make-socket :connect :passive
                                             :local-host host
                                             :local-port port
                                             :reuse-address t))
    (with-open-stream (stream (ccl:accept-connection server))
      (format out "~s~%" (read stream))
      (print :pong stream)
      (finish-output stream))))

(defun make-socket/retry (host port tries)
  (loop (handler-case (return (ccl:make-socket :remote-host host
                                               :remote-port port))
          (ccl:socket-creation-error (err)
            (unless (plusp (decf tries)) (error err))
            (format t "retry~%")
            (sleep 0.1)))))

(defun test (host port)
  (ccl:process-run-function "server" #'run-server
                            host port *standard-output*)
  ;(sleep 0.001)
  (with-open-stream (stream (make-socket/retry host port 5))
    (print :ping stream)
    (finish-output stream)
    (format t "~s~%" (read stream))))

(defun run ()
  (loop for port from 10000 to 20000 do (test "localhost" port)))

Failure happens within three iterations on my machine.

retry
:PING
:PONG
retry
> Error: on #<CCL::LISTENER-SOCKET #x1866FB36> : 
>        Bad file descriptor (error #9) during accept
> While executing: SOCKET-ERROR, in process server(3).

or

retry
:PING
:PONG
retry
> Error: Bad file descriptor (error #9) during socket creation operation in bind
> While executing: SOCKET-ERROR, in process server(3).

or

retry
:PING
:PONG
retry
:PING
:PONG
retry
> Error: Bad file descriptor (error #9) during socket creation operation in listen
> While executing: SOCKET-ERROR, in process server(4).

Adding the SLEEP call after PROCESS-RUN-FUNCTION prevents all errors.

Tested on 1.9-dev-r15576M-trunk (LinuxX8632). Failure on Darwin has happened but is very rare; I've only seen it twice.

I can work around this issue by handling/retrying, however CCL is the only implementation which requires this special attention.

Change History

comment:1 Changed 21 months ago by gb

  • Status changed from new to closed
  • Resolution set to fixed

(In [15599]) Don't close the fd on error in %SOCKET-CONNECT; callers will try to close it again in an UNWIND-PROTECT cleanup, and it may have been reopened in another thread.

Fixes ticket:1050 in the trunk.

Note: See TracTickets for help on using tickets.