First, the documentation for wait-for-input says that only integer are accepted, but code seems to think reals should work. (Tested on SBCL/Windows.)
Second, I have found a bug in wait-for-input in SBCL on Windows. The problem is that a wait-for-input on a TCP server socket which has already accepted one client will continue to return that the socket is ready to accept more clients even though it isn't, and thus cause an error when I try to call socket-accept. Here is the code that breaks it:
(defvar *port* 12345) (defvar *socket-server-listen* (socket-listen *wildcard-host* *port* :element-type '(unsigned-byte 8)))
(defvar *socket-server-connection*) (setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "First time (before client connects) is ~s.~%" *socket-server-connection*)
(defvar *socket-client-connection*) (setf *socket-client-connection* (socket-connect "localhost" *port* :protocol :stream :element-type '(unsigned-byte 8) :timeout 0))
(setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "Second time (after client connects) is ~s.~%" *socket-server-connection*)
(setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "Third time (before second client) is ~s.~%" *socket-server-connection*)
The output on Windows/SBCL looks like:
First time (before client connects) is NIL. Second time (after client connects) is #<STREAM-USOCKET {24757F91}>.
It doesn't get to the first format call, because it hits the following error first:
Condition BAD-FILE-DESCRIPTOR-ERROR was signalled. [Condition of type BAD-FILE-DESCRIPTOR-ERROR]
Restarts: 0: [RETRY] Retry SLIME REPL evaluation request. 1: [ABORT] Return to SLIME's top level. 2: [ABORT] Abort 3: [CLOSE-CONNECTION] Close SLIME connection 4: [ABORT] Exit debugger, returning to top level.
Backtrace: 0: (USOCKET::HANDLE-CONDITION #<SB-BSD-SOCKETS:SOCKET-ERROR {2475C889}> #<STREAM-SERVER-USOCKET {256F7C19}>) 1: (SIGNAL #<SB-BSD-SOCKETS:SOCKET-ERROR {2475C889}>) 2: (ERROR SB-BSD-SOCKETS:SOCKET-ERROR :ERRNO 9 :SYSCALL "accept") 3: (SB-BSD-SOCKETS:SOCKET-ERROR "accept") 4: ((SB-PCL::FAST-METHOD SB-BSD-SOCKETS:SOCKET-ACCEPT (SB-BSD-SOCKETS:SOCKET)) #<unavailable argument> #<unavailable argument> #<SB-BSD-SOCKETS:INET-SOCKET 0.0.0.0:12345, fd: 6 {2576DD91}>) 5: ((SB-PCL::FAST-METHOD SOCKET-ACCEPT (STREAM-SERVER-USOCKET)) #<unused argument> #<unused argument> #<STREAM-SERVER-USOCKET {256F7C19}> :ELEMENT-TYPE NIL) 6: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*) #<NULL-LEXENV>) 7: (SB-INT:SIMPLE-EVAL-IN-LEXENV (PROGN (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*)) #<NULL-LEXENV>) 8: (SB-INT:SIMPLE-EVAL-IN-LEXENV (WHEN (WAIT-FOR-INPUT *SOCKET-SERVER-LISTEN* :TIMEOUT 0 :READY-ONLY T) (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*)) #<NULL-LEXENV>) 9: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SETF *SOCKET-SERVER-CONNECTION* (WHEN # #)) #<NULL-LEXENV>)
Hi, Elliott
Sorry for late responses, I'm a little busy in the past week.
It seems that current implementation of WAIT-FOR-INPUT on SBCL/Windows have some bugs, I'll look into it in next two days and try to fix it. Whatever bug it has, it shuold NOT be any bug in SBCL itself, because this function was completely written using SB-ALIEN and underlying Win32 API.
I'll put your code as part of usocket's unit test and see if it also affects other backends.
Regards,
Chun Tian (binghe)
在 2011-4-25,09:17, Elliott Slaughter 写道:
First, the documentation for wait-for-input says that only integer are accepted, but code seems to think reals should work. (Tested on SBCL/Windows.)
Second, I have found a bug in wait-for-input in SBCL on Windows. The problem is that a wait-for-input on a TCP server socket which has already accepted one client will continue to return that the socket is ready to accept more clients even though it isn't, and thus cause an error when I try to call socket-accept. Here is the code that breaks it:
(defvar *port* 12345) (defvar *socket-server-listen* (socket-listen *wildcard-host* *port* :element-type '(unsigned-byte 8)))
(defvar *socket-server-connection*) (setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "First time (before client connects) is ~s.~%" *socket-server-connection*)
(defvar *socket-client-connection*) (setf *socket-client-connection* (socket-connect "localhost" *port* :protocol :stream :element-type '(unsigned-byte 8) :timeout 0))
(setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "Second time (after client connects) is ~s.~%" *socket-server-connection*)
(setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "Third time (before second client) is ~s.~%" *socket-server-connection*)
The output on Windows/SBCL looks like:
First time (before client connects) is NIL. Second time (after client connects) is #<STREAM-USOCKET {24757F91}>.
It doesn't get to the first format call, because it hits the following error first:
Condition BAD-FILE-DESCRIPTOR-ERROR was signalled. [Condition of type BAD-FILE-DESCRIPTOR-ERROR]
Restarts: 0: [RETRY] Retry SLIME REPL evaluation request. 1: [ABORT] Return to SLIME's top level. 2: [ABORT] Abort 3: [CLOSE-CONNECTION] Close SLIME connection 4: [ABORT] Exit debugger, returning to top level.
Backtrace: 0: (USOCKET::HANDLE-CONDITION #<SB-BSD-SOCKETS:SOCKET-ERROR {2475C889}> #<STREAM-SERVER-USOCKET {256F7C19}>) 1: (SIGNAL #<SB-BSD-SOCKETS:SOCKET-ERROR {2475C889}>) 2: (ERROR SB-BSD-SOCKETS:SOCKET-ERROR :ERRNO 9 :SYSCALL "accept") 3: (SB-BSD-SOCKETS:SOCKET-ERROR "accept") 4: ((SB-PCL::FAST-METHOD SB-BSD-SOCKETS:SOCKET-ACCEPT (SB-BSD-SOCKETS:SOCKET)) #<unavailable argument> #<unavailable argument> #<SB-BSD-SOCKETS:INET-SOCKET 0.0.0.0:12345, fd: 6 {2576DD91}>) 5: ((SB-PCL::FAST-METHOD SOCKET-ACCEPT (STREAM-SERVER-USOCKET)) #<unused argument> #<unused argument> #<STREAM-SERVER-USOCKET {256F7C19}> :ELEMENT-TYPE NIL) 6: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*) #<NULL-LEXENV>) 7: (SB-INT:SIMPLE-EVAL-IN-LEXENV (PROGN (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*)) #<NULL-LEXENV>) 8: (SB-INT:SIMPLE-EVAL-IN-LEXENV (WHEN (WAIT-FOR-INPUT *SOCKET-SERVER-LISTEN* :TIMEOUT 0 :READY-ONLY T) (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*)) #<NULL-LEXENV>) 9: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SETF *SOCKET-SERVER-CONNECTION* (WHEN # #)) #<NULL-LEXENV>)
-- Elliott Slaughter
"Don't worry about what anybody else is going to do. The best way to predict the future is to invent it." - Alan Kay _______________________________________________ usocket-devel mailing list usocket-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/usocket-devel
By the way (in case you have any trouble reproducing), the version of SBCL used to test this can be obtained here. (It's just a more up-to-date version than what you can get on the SBCL download page that I compiled myself.
http://elliottslaughter.net/files/sbcl-1.0.46.msi
2011/4/30 Chun Tian (binghe) binghe.lisp@gmail.com
Hi, Elliott
Sorry for late responses, I'm a little busy in the past week.
It seems that current implementation of WAIT-FOR-INPUT on SBCL/Windows have some bugs, I'll look into it in next two days and try to fix it. Whatever bug it has, it shuold NOT be any bug in SBCL itself, because this function was completely written using SB-ALIEN and underlying Win32 API.
I'll put your code as part of usocket's unit test and see if it also affects other backends.
Regards,
Chun Tian (binghe)
在 2011-4-25,09:17, Elliott Slaughter 写道:
First, the documentation for wait-for-input says that only integer are accepted, but code seems to think reals should work. (Tested on SBCL/Windows.)
Second, I have found a bug in wait-for-input in SBCL on Windows. The problem is that a wait-for-input on a TCP server socket which has already accepted one client will continue to return that the socket is ready to accept more clients even though it isn't, and thus cause an error when I try to call socket-accept. Here is the code that breaks it:
(defvar *port* 12345) (defvar *socket-server-listen* (socket-listen *wildcard-host* *port* :element-type '(unsigned-byte 8)))
(defvar *socket-server-connection*) (setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "First time (before client connects) is ~s.~%" *socket-server-connection*)
(defvar *socket-client-connection*) (setf *socket-client-connection* (socket-connect "localhost" *port* :protocol :stream :element-type '(unsigned-byte 8) :timeout 0))
(setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "Second time (after client connects) is ~s.~%" *socket-server-connection*)
(setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "Third time (before second client) is ~s.~%" *socket-server-connection*)
The output on Windows/SBCL looks like:
First time (before client connects) is NIL. Second time (after client connects) is #<STREAM-USOCKET {24757F91}>.
It doesn't get to the first format call, because it hits the following error first:
Condition BAD-FILE-DESCRIPTOR-ERROR was signalled. [Condition of type BAD-FILE-DESCRIPTOR-ERROR]
Restarts: 0: [RETRY] Retry SLIME REPL evaluation request. 1: [ABORT] Return to SLIME's top level. 2: [ABORT] Abort 3: [CLOSE-CONNECTION] Close SLIME connection 4: [ABORT] Exit debugger, returning to top level.
Backtrace: 0: (USOCKET::HANDLE-CONDITION #<SB-BSD-SOCKETS:SOCKET-ERROR {2475C889}> #<STREAM-SERVER-USOCKET {256F7C19}>) 1: (SIGNAL #<SB-BSD-SOCKETS:SOCKET-ERROR {2475C889}>) 2: (ERROR SB-BSD-SOCKETS:SOCKET-ERROR :ERRNO 9 :SYSCALL "accept") 3: (SB-BSD-SOCKETS:SOCKET-ERROR "accept") 4: ((SB-PCL::FAST-METHOD SB-BSD-SOCKETS:SOCKET-ACCEPT (SB-BSD-SOCKETS:SOCKET)) #<unavailable argument> #<unavailable argument> #<SB-BSD-SOCKETS:INET-SOCKET 0.0.0.0:12345, fd: 6 {2576DD91}>) 5: ((SB-PCL::FAST-METHOD SOCKET-ACCEPT (STREAM-SERVER-USOCKET)) #<unused argument> #<unused argument> #<STREAM-SERVER-USOCKET {256F7C19}> :ELEMENT-TYPE NIL) 6: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*) #<NULL-LEXENV>) 7: (SB-INT:SIMPLE-EVAL-IN-LEXENV (PROGN (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*)) #<NULL-LEXENV>) 8: (SB-INT:SIMPLE-EVAL-IN-LEXENV (WHEN (WAIT-FOR-INPUT *SOCKET-SERVER-LISTEN* :TIMEOUT 0 :READY-ONLY T) (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*)) #<NULL-LEXENV>) 9: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SETF *SOCKET-SERVER-CONNECTION* (WHEN # #)) #<NULL-LEXENV>)
-- Elliott Slaughter
"Don't worry about what anybody else is going to do. The best way to predict the future is to invent it." - Alan Kay _______________________________________________ usocket-devel mailing list usocket-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/usocket-devel
Hi, Elliott
Thank you, I've installed this SBCL binary and merged your test code into usocket's unit test [1]. And Yes, I can see the BAD-FILE-DESCRIPTOR-ERROR now. This happens only on SBCL/Windows but other platforms. I also tried your test code on other CL implementations, it passed on most backends on Mac OS (CMUCL, SBCL, Allegro CL, Clozure CL) but strangely failed on LispWorks/Mac in another form, and hang forever on ABCL ... Any way, let me try to fix SBCL/Windows first.
Regards,
Chun Tian (binghe)
[1] svn://common-lisp.net/project/usocket/svn/usocket/branches/0.5.x/test/wait-for-input.lisp
在 2011-5-1,01:48, Elliott Slaughter 写道:
By the way (in case you have any trouble reproducing), the version of SBCL used to test this can be obtained here. (It's just a more up-to-date version than what you can get on the SBCL download page that I compiled myself.
http://elliottslaughter.net/files/sbcl-1.0.46.msi
2011/4/30 Chun Tian (binghe) binghe.lisp@gmail.com Hi, Elliott
Sorry for late responses, I'm a little busy in the past week.
It seems that current implementation of WAIT-FOR-INPUT on SBCL/Windows have some bugs, I'll look into it in next two days and try to fix it. Whatever bug it has, it shuold NOT be any bug in SBCL itself, because this function was completely written using SB-ALIEN and underlying Win32 API.
I'll put your code as part of usocket's unit test and see if it also affects other backends.
Regards,
Chun Tian (binghe)
在 2011-4-25,09:17, Elliott Slaughter 写道:
First, the documentation for wait-for-input says that only integer are accepted, but code seems to think reals should work. (Tested on SBCL/Windows.)
Second, I have found a bug in wait-for-input in SBCL on Windows. The problem is that a wait-for-input on a TCP server socket which has already accepted one client will continue to return that the socket is ready to accept more clients even though it isn't, and thus cause an error when I try to call socket-accept. Here is the code that breaks it:
(defvar *port* 12345) (defvar *socket-server-listen* (socket-listen *wildcard-host* *port* :element-type '(unsigned-byte 8)))
(defvar *socket-server-connection*) (setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "First time (before client connects) is ~s.~%" *socket-server-connection*)
(defvar *socket-client-connection*) (setf *socket-client-connection* (socket-connect "localhost" *port* :protocol :stream :element-type '(unsigned-byte 8) :timeout 0))
(setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "Second time (after client connects) is ~s.~%" *socket-server-connection*)
(setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "Third time (before second client) is ~s.~%" *socket-server-connection*)
The output on Windows/SBCL looks like:
First time (before client connects) is NIL. Second time (after client connects) is #<STREAM-USOCKET {24757F91}>.
It doesn't get to the first format call, because it hits the following error first:
Condition BAD-FILE-DESCRIPTOR-ERROR was signalled. [Condition of type BAD-FILE-DESCRIPTOR-ERROR]
Restarts: 0: [RETRY] Retry SLIME REPL evaluation request. 1: [ABORT] Return to SLIME's top level. 2: [ABORT] Abort 3: [CLOSE-CONNECTION] Close SLIME connection 4: [ABORT] Exit debugger, returning to top level.
Backtrace: 0: (USOCKET::HANDLE-CONDITION #<SB-BSD-SOCKETS:SOCKET-ERROR {2475C889}> #<STREAM-SERVER-USOCKET {256F7C19}>) 1: (SIGNAL #<SB-BSD-SOCKETS:SOCKET-ERROR {2475C889}>) 2: (ERROR SB-BSD-SOCKETS:SOCKET-ERROR :ERRNO 9 :SYSCALL "accept") 3: (SB-BSD-SOCKETS:SOCKET-ERROR "accept") 4: ((SB-PCL::FAST-METHOD SB-BSD-SOCKETS:SOCKET-ACCEPT (SB-BSD-SOCKETS:SOCKET)) #<unavailable argument> #<unavailable argument> #<SB-BSD-SOCKETS:INET-SOCKET 0.0.0.0:12345, fd: 6 {2576DD91}>) 5: ((SB-PCL::FAST-METHOD SOCKET-ACCEPT (STREAM-SERVER-USOCKET)) #<unused argument> #<unused argument> #<STREAM-SERVER-USOCKET {256F7C19}> :ELEMENT-TYPE NIL) 6: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*) #<NULL-LEXENV>) 7: (SB-INT:SIMPLE-EVAL-IN-LEXENV (PROGN (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*)) #<NULL-LEXENV>) 8: (SB-INT:SIMPLE-EVAL-IN-LEXENV (WHEN (WAIT-FOR-INPUT *SOCKET-SERVER-LISTEN* :TIMEOUT 0 :READY-ONLY T) (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*)) #<NULL-LEXENV>) 9: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SETF *SOCKET-SERVER-CONNECTION* (WHEN # #)) #<NULL-LEXENV>)
-- Elliott Slaughter
"Don't worry about what anybody else is going to do. The best way to predict the future is to invent it." - Alan Kay _______________________________________________ usocket-devel mailing list usocket-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/usocket-devel
-- Elliott Slaughter
"Don't worry about what anybody else is going to do. The best way to predict the future is to invent it." - Alan Kay
Hi, Elliott
I believe this bug was now fixed. The third WAIT-FOR-INPUT in your test code shouldn't return a non-NIL value, but a bug in function WAIT-FOR-INPUT caused the "last" status of sockets didn't been reset correctly.
This bug only affect SBCL and ECL on Windows, and was fixed in r653 on USOCKET 0.5.x branch [1].
Please update your USOCKET and confirm if it works for you (and report back, if possible), and I'll see your another bug report in a moment.
Regards,
Chun Tian (binghe)
P. S. Your test code also let me find a bug in LispWorks' version of SOCKET-ACCEPT, and I've done a fix based on completely different theory. Thanks.
[1] svn://common-lisp.net/project/usocket/svn/usocket/branches/0.5.x
在 2011-4-25,09:17, Elliott Slaughter 写道:
First, the documentation for wait-for-input says that only integer are accepted, but code seems to think reals should work. (Tested on SBCL/Windows.)
Second, I have found a bug in wait-for-input in SBCL on Windows. The problem is that a wait-for-input on a TCP server socket which has already accepted one client will continue to return that the socket is ready to accept more clients even though it isn't, and thus cause an error when I try to call socket-accept. Here is the code that breaks it:
(defvar *port* 12345) (defvar *socket-server-listen* (socket-listen *wildcard-host* *port* :element-type '(unsigned-byte 8)))
(defvar *socket-server-connection*) (setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "First time (before client connects) is ~s.~%" *socket-server-connection*)
(defvar *socket-client-connection*) (setf *socket-client-connection* (socket-connect "localhost" *port* :protocol :stream :element-type '(unsigned-byte 8) :timeout 0))
(setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "Second time (after client connects) is ~s.~%" *socket-server-connection*)
(setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "Third time (before second client) is ~s.~%" *socket-server-connection*)
The output on Windows/SBCL looks like:
First time (before client connects) is NIL. Second time (after client connects) is #<STREAM-USOCKET {24757F91}>.
It doesn't get to the first format call, because it hits the following error first:
Condition BAD-FILE-DESCRIPTOR-ERROR was signalled. [Condition of type BAD-FILE-DESCRIPTOR-ERROR]
Restarts: 0: [RETRY] Retry SLIME REPL evaluation request. 1: [ABORT] Return to SLIME's top level. 2: [ABORT] Abort 3: [CLOSE-CONNECTION] Close SLIME connection 4: [ABORT] Exit debugger, returning to top level.
Backtrace: 0: (USOCKET::HANDLE-CONDITION #<SB-BSD-SOCKETS:SOCKET-ERROR {2475C889}> #<STREAM-SERVER-USOCKET {256F7C19}>) 1: (SIGNAL #<SB-BSD-SOCKETS:SOCKET-ERROR {2475C889}>) 2: (ERROR SB-BSD-SOCKETS:SOCKET-ERROR :ERRNO 9 :SYSCALL "accept") 3: (SB-BSD-SOCKETS:SOCKET-ERROR "accept") 4: ((SB-PCL::FAST-METHOD SB-BSD-SOCKETS:SOCKET-ACCEPT (SB-BSD-SOCKETS:SOCKET)) #<unavailable argument> #<unavailable argument> #<SB-BSD-SOCKETS:INET-SOCKET 0.0.0.0:12345, fd: 6 {2576DD91}>) 5: ((SB-PCL::FAST-METHOD SOCKET-ACCEPT (STREAM-SERVER-USOCKET)) #<unused argument> #<unused argument> #<STREAM-SERVER-USOCKET {256F7C19}> :ELEMENT-TYPE NIL) 6: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*) #<NULL-LEXENV>) 7: (SB-INT:SIMPLE-EVAL-IN-LEXENV (PROGN (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*)) #<NULL-LEXENV>) 8: (SB-INT:SIMPLE-EVAL-IN-LEXENV (WHEN (WAIT-FOR-INPUT *SOCKET-SERVER-LISTEN* :TIMEOUT 0 :READY-ONLY T) (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*)) #<NULL-LEXENV>) 9: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SETF *SOCKET-SERVER-CONNECTION* (WHEN # #)) #<NULL-LEXENV>)
-- Elliott Slaughter
"Don't worry about what anybody else is going to do. The best way to predict the future is to invent it." - Alan Kay _______________________________________________ usocket-devel mailing list usocket-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/usocket-devel
Yes, the test suite now passes the tests for this.
My application still breaks as reported in my other emails, so it's a little hard to test this on my real code.
Thanks!
2011/5/1 Chun Tian (binghe) binghe.lisp@gmail.com
Hi, Elliott
I believe this bug was now fixed. The third WAIT-FOR-INPUT in your test code shouldn't return a non-NIL value, but a bug in function WAIT-FOR-INPUT caused the "last" status of sockets didn't been reset correctly.
This bug only affect SBCL and ECL on Windows, and was fixed in r653 on USOCKET 0.5.x branch [1].
Please update your USOCKET and confirm if it works for you (and report back, if possible), and I'll see your another bug report in a moment.
Regards,
Chun Tian (binghe)
P. S. Your test code also let me find a bug in LispWorks' version of SOCKET-ACCEPT, and I've done a fix based on completely different theory. Thanks.
[1] svn://common-lisp.net/project/usocket/svn/usocket/branches/0.5.x
在 2011-4-25,09:17, Elliott Slaughter 写道:
First, the documentation for wait-for-input says that only integer are accepted, but code seems to think reals should work. (Tested on SBCL/Windows.)
Second, I have found a bug in wait-for-input in SBCL on Windows. The problem is that a wait-for-input on a TCP server socket which has already accepted one client will continue to return that the socket is ready to accept more clients even though it isn't, and thus cause an error when I try to call socket-accept. Here is the code that breaks it:
(defvar *port* 12345) (defvar *socket-server-listen* (socket-listen *wildcard-host* *port* :element-type '(unsigned-byte 8)))
(defvar *socket-server-connection*) (setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "First time (before client connects) is ~s.~%" *socket-server-connection*)
(defvar *socket-client-connection*) (setf *socket-client-connection* (socket-connect "localhost" *port* :protocol :stream :element-type '(unsigned-byte 8) :timeout 0))
(setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "Second time (after client connects) is ~s.~%" *socket-server-connection*)
(setf *socket-server-connection* (when (wait-for-input *socket-server-listen* :timeout 0 :ready-only t) (socket-accept *socket-server-listen*))) (format t "Third time (before second client) is ~s.~%" *socket-server-connection*)
The output on Windows/SBCL looks like:
First time (before client connects) is NIL. Second time (after client connects) is #<STREAM-USOCKET {24757F91}>.
It doesn't get to the first format call, because it hits the following error first:
Condition BAD-FILE-DESCRIPTOR-ERROR was signalled. [Condition of type BAD-FILE-DESCRIPTOR-ERROR]
Restarts: 0: [RETRY] Retry SLIME REPL evaluation request. 1: [ABORT] Return to SLIME's top level. 2: [ABORT] Abort 3: [CLOSE-CONNECTION] Close SLIME connection 4: [ABORT] Exit debugger, returning to top level.
Backtrace: 0: (USOCKET::HANDLE-CONDITION #<SB-BSD-SOCKETS:SOCKET-ERROR {2475C889}> #<STREAM-SERVER-USOCKET {256F7C19}>) 1: (SIGNAL #<SB-BSD-SOCKETS:SOCKET-ERROR {2475C889}>) 2: (ERROR SB-BSD-SOCKETS:SOCKET-ERROR :ERRNO 9 :SYSCALL "accept") 3: (SB-BSD-SOCKETS:SOCKET-ERROR "accept") 4: ((SB-PCL::FAST-METHOD SB-BSD-SOCKETS:SOCKET-ACCEPT (SB-BSD-SOCKETS:SOCKET)) #<unavailable argument> #<unavailable argument> #<SB-BSD-SOCKETS:INET-SOCKET 0.0.0.0:12345, fd: 6 {2576DD91}>) 5: ((SB-PCL::FAST-METHOD SOCKET-ACCEPT (STREAM-SERVER-USOCKET)) #<unused argument> #<unused argument> #<STREAM-SERVER-USOCKET {256F7C19}> :ELEMENT-TYPE NIL) 6: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*) #<NULL-LEXENV>) 7: (SB-INT:SIMPLE-EVAL-IN-LEXENV (PROGN (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*)) #<NULL-LEXENV>) 8: (SB-INT:SIMPLE-EVAL-IN-LEXENV (WHEN (WAIT-FOR-INPUT *SOCKET-SERVER-LISTEN* :TIMEOUT 0 :READY-ONLY T) (SOCKET-ACCEPT *SOCKET-SERVER-LISTEN*)) #<NULL-LEXENV>) 9: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SETF *SOCKET-SERVER-CONNECTION* (WHEN # #)) #<NULL-LEXENV>)
-- Elliott Slaughter
"Don't worry about what anybody else is going to do. The best way to predict the future is to invent it." - Alan Kay _______________________________________________ usocket-devel mailing list usocket-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/usocket-devel