Changeset 3725
- Timestamp:
- 08/07/08 14:54:38 (4 months ago)
- Files:
-
- trunk/thirdparty/usocket/Makefile (modified) (1 diff)
- trunk/thirdparty/usocket/README (modified) (2 diffs)
- trunk/thirdparty/usocket/TODO (modified) (1 diff)
- trunk/thirdparty/usocket/backend/allegro.lisp (modified) (4 diffs)
- trunk/thirdparty/usocket/backend/armedbear.lisp (modified) (10 diffs)
- trunk/thirdparty/usocket/backend/clisp.lisp (modified) (4 diffs)
- trunk/thirdparty/usocket/backend/cmucl.lisp (modified) (6 diffs)
- trunk/thirdparty/usocket/backend/lispworks.lisp (modified) (13 diffs)
- trunk/thirdparty/usocket/backend/openmcl.lisp (modified) (6 diffs)
- trunk/thirdparty/usocket/backend/sbcl.lisp (modified) (11 diffs)
- trunk/thirdparty/usocket/backend/scl.lisp (modified) (6 diffs)
- trunk/thirdparty/usocket/condition.lisp (modified) (3 diffs)
- trunk/thirdparty/usocket/package.lisp (modified) (5 diffs)
- trunk/thirdparty/usocket/test/package.lisp (modified) (1 diff)
- trunk/thirdparty/usocket/test/test-usocket.lisp (modified) (1 diff)
- trunk/thirdparty/usocket/test/usocket-test.asd (modified) (1 diff)
- trunk/thirdparty/usocket/usocket.asd (modified) (1 diff)
- trunk/thirdparty/usocket/usocket.lisp (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/thirdparty/usocket/Makefile
r3183 r3725 1 1 # $Id: Makefile 80 2006-02-12 10:09:49Z ehuelsmann $ 2 # $URL: svn ://common-lisp.net/project/usocket/svn/usocket/branches/hans/Makefile $2 # $URL: svn+ssh://common-lisp.net/project/usocket/svn/usocket/branches/0.4.x/Makefile $ 3 3 4 4 clean: trunk/thirdparty/usocket/README
r3183 r3725 1 1 -*- text -*- 2 2 3 $Id: README 334 2008-04-23 21:24:15Z hhubner$3 $Id: README 249 2007-05-20 14:16:12Z ehuelsmann $ 4 4 5 5 Content … … 96 96 97 97 98 99 98 100 Errors: 99 101 - address-in-use-error trunk/thirdparty/usocket/TODO
r3183 r3725 2 2 - Implement wait-for-input-internal for 3 3 * SBCL Win32 4 * LispWorks Win325 4 6 5 - Implement errors for (the alien interface code of) trunk/thirdparty/usocket/backend/allegro.lisp
r3497 r3725 1 ;;;; $Id: allegro.lisp 335 2008-04-23 21:29:50Z hhubner$2 ;;;; $URL: svn ://common-lisp.net/project/usocket/svn/usocket/branches/hans/backend/allegro.lisp $1 ;;;; $Id: allegro.lisp 405 2008-07-30 19:26:46Z ehuelsmann $ 2 ;;;; $URL: svn+ssh://common-lisp.net/project/usocket/svn/usocket/branches/0.4.x/backend/allegro.lisp $ 3 3 4 4 ;;;; See LICENSE for licensing information. … … 50 50 :binary)) 51 51 52 (defun socket-connect (host port &key (element-type 'character) timeout nodelay) 53 (declare (ignore nodelay)) 54 (when timeout 55 (warn "SOCKET-CONNECT timeout not supported in Allegro CL")) 52 (defun socket-connect (host port &key (element-type 'character) 53 timeout deadline 54 (nodelay t) ;; nodelay == t is the ACL default 55 local-host local-port) 56 (when timeout (unsupported 'timeout 'socket-connect)) 57 (when deadline (unsupported 'deadline 'socket-connect)) 58 56 59 (let ((socket)) 57 60 (setf socket 58 61 (with-mapped-conditions (socket) 62 (if timeout 63 (mp:with-timeout (timeout nil) 64 (socket:make-socket :remote-host (host-to-hostname host) 65 :remote-port port 66 :local-host (when local-host (host-to-hostname local-host)) 67 :local-port local-port 68 :format (to-format element-type) 69 :nodelay nodelay)) 59 70 (socket:make-socket :remote-host (host-to-hostname host) 60 71 :remote-port port 61 :format (to-format element-type)))) 72 :local-host local-host 73 :local-port local-port 74 :format (to-format element-type) 75 :nodelay nodelay)))) 62 76 (make-stream-socket :socket socket :stream socket))) 63 77 … … 67 81 (defmethod socket-close ((usocket usocket)) 68 82 "Close socket." 83 (when (wait-list usocket) 84 (remove-waiter (wait-list usocket) usocket)) 69 85 (with-mapped-conditions (usocket) 70 86 (close (socket usocket)))) … … 131 147 (host-to-hostname name)))))) 132 148 133 (defun wait-for-input-internal (sockets &key timeout) 149 (defun %setup-wait-list (wait-list) 150 (declare (ignore wait-list))) 151 152 (defun %add-waiter (wait-list waiter) 153 (push (socket waiter) (wait-list-%wait wait-list))) 154 155 (defun %remove-waiter (wait-list waiter) 156 (setf (wait-list-%wait wait-list) 157 (remove (socket waiter) (wait-list-%wait wait-list)))) 158 159 (defun wait-for-input-internal (wait-list &key timeout) 134 160 (with-mapped-conditions () 135 161 (let ((active-internal-sockets 136 162 (if timeout 137 (mp:wait-for-input-available ( mapcar #'socket sockets)163 (mp:wait-for-input-available (wait-list-%wait wait-list) 138 164 :timeout timeout) 139 (mp:wait-for-input-available ( mapcar #'socket sockets)))))165 (mp:wait-for-input-available (wait-list-%wait wait-list))))) 140 166 ;; this is quadratic, but hey, the active-internal-sockets 141 167 ;; list is very short and it's only quadratic in the length of that one. 142 168 ;; When I have more time I could recode it to something of linear 143 169 ;; complexity. 144 ;; [Same code is also used in lispworks.lisp, openmcl.lisp] 145 (remove-if #'(lambda (x) 146 (not (member (socket x) active-internal-sockets))) 147 sockets)))) 170 ;; [Same code is also used in openmcl.lisp] 171 (dolist (x active-internal-sockets) 172 (setf (state (gethash x (wait-list-map wait-list))) 173 :READ)) 174 wait-list))) trunk/thirdparty/usocket/backend/armedbear.lisp
r3497 r3725 1 ;;;; $Id: armedbear.lisp 335 2008-04-23 21:29:50Z hhubner$2 ;;;; $URL: svn ://common-lisp.net/project/usocket/svn/usocket/branches/hans/backend/armedbear.lisp $1 ;;;; $Id: armedbear.lisp 409 2008-07-31 05:50:06Z ehuelsmann $ 2 ;;;; $URL: svn+ssh://common-lisp.net/project/usocket/svn/usocket/branches/0.4.x/backend/armedbear.lisp $ 3 3 4 4 ;;;; See LICENSE for licensing information. … … 89 89 (java:jclass-name (jop-class instance))))) 90 90 91 (declaim (inline jop-deref)) 91 92 (defun jop-deref (instance) 92 93 (if (java-object-proxy-p instance) … … 186 187 (error (error 'unknown-error :socket socket :real-error condition)))) 187 188 188 (defun socket-connect (host port &key (element-type 'character) timeout nodelay) 189 (declare (ignore nodelay)) 190 (when timeout 191 (warn "SOCKET-CONNECT timeout not supported in ABCL")) 189 (defun socket-connect (host port &key (element-type 'character) 190 timeout deadline (nodelay nil nodelay-specified) 191 local-host local-port) 192 (when deadline (unsupported 'deadline 'socket-connect)) 193 (when (or local-host local-port) 194 (unimplemented 'local-host 'socket-connect) 195 (unimplemented 'local-port 'socket-connect)) 196 192 197 (let ((usock)) 193 198 (with-mapped-conditions (usock) … … 200 205 "open" sock-addr)) 201 206 (sock (jdi:do-jmethod-call jchan "socket"))) 202 (describe sock) 207 (when nodelay-specified 208 (jdi:do-jmethod-call sock "setTcpNoDelay" 209 (if nodelay 210 (java:make-immediate-object t :boolean) 211 (java:make-immediate-object nil :boolean)))) 212 (when timeout 213 (jdi:do-jmethod-call sock "setSoTimeout" 214 (truncate (* 1000 timeout)))) 203 215 (setf usock 204 216 (make-stream-socket … … 249 261 250 262 (defmethod socket-close ((usocket usocket)) 263 (when (wait-list usocket) 264 (remove-waiter (wait-list usocket) usocket)) 251 265 (with-mapped-conditions (usocket) 252 266 (jdi:do-jmethod (socket usocket) "close"))) … … 256 270 ;; its buffers *and* closes the socket. 257 271 (defmethod socket-close ((usocket stream-usocket)) 272 (when (wait-list usocket) 273 (remove-waiter (wait-list usocket) usocket)) 258 274 (with-mapped-conditions (usocket) 259 275 (close (socket-stream usocket)))) 260 276 261 277 (defmethod get-local-address ((usocket usocket)) 262 (dotted-quad-to-vector-quad (ext:socket-local-address (socket usocket)))) 278 (dotted-quad-to-vector-quad (ext:socket-local-address 279 (jdi:jop-deref 280 (jdi:do-jmethod-call (socket usocket) 281 "socket"))))) 263 282 264 283 (defmethod get-peer-address ((usocket stream-usocket)) 265 (dotted-quad-to-vector-quad (ext:socket-peer-address (socket usocket)))) 284 (dotted-quad-to-vector-quad (ext:socket-peer-address 285 (jdi:jop-deref 286 (jdi:do-jmethod-call (socket usocket) 287 "socket"))))) 266 288 267 289 (defmethod get-local-port ((usocket usocket)) 268 (ext:socket-local-port (socket usocket))) 290 (ext:socket-local-port (jdi:jop-deref 291 (jdi:do-jmethod-call (socket usocket) "socket")))) 269 292 270 293 (defmethod get-peer-port ((usocket stream-usocket)) 271 (ext:socket-peer-port (socket usocket))) 294 (ext:socket-peer-port (jdi:jop-deref 295 (jdi:do-jmethod-call (socket usocket) "socket")))) 272 296 273 297 (defmethod get-local-name ((usocket usocket)) … … 353 377 "java.nio.channels.DatagramChannel"))) 354 378 355 (defun wait-for-input-internal (sockets &key timeout) 356 (let* ((ops (logior (op-read) (op-accept))) 379 (defun wait-for-input-internal (wait-list &key timeout) 380 (let* ((sockets (wait-list-waiters wait-list)) 381 (ops (logior (op-read) (op-accept))) 357 382 (selector (jdi:do-jstatic "java.nio.channels.Selector" "open")) 358 383 (channels (mapcar #'socket sockets))) 359 384 (unwind-protect 360 385 (with-mapped-conditions () 361 (let ((jfalse (java:make-immediate-object nil :boolean)) 362 (sel (jdi:jop-deref selector))) 386 (let ((sel (jdi:jop-deref selector))) 363 387 (dolist (channel channels) 364 388 (let ((chan (jdi:jop-deref channel))) … … 366 390 "configureBlocking" 367 391 "boolean") 368 chan jfalse)392 chan (java:make-immediate-object nil :boolean)) 369 393 (java:jcall (java:jmethod "java.nio.channels.SelectableChannel" 370 394 "register" … … 380 404 (let* ((selkeys (jdi:do-jmethod selector "selectedKeys")) 381 405 (selkey-iterator (jdi:do-jmethod selkeys "iterator")) 382 ready-sockets)406 (%wait (wait-list-%wait wait-list))) 383 407 (loop while (java:jcall 384 408 (java:jmethod "java.util.Iterator" "hasNext") … … 389 413 (chan (jdi:jop-deref 390 414 (jdi:do-jmethod key "channel")))) 391 (push chan ready-sockets))) 392 (remove-if #'(lambda (s) 393 (not (member (jdi:jop-deref (socket s)) 394 ready-sockets 395 :test #'(lambda (x y) 396 (java:jcall (java:jmethod "java.lang.Object" 397 "equals" 398 "java.lang.Object") 399 x y))))) 400 sockets)))))) 401 ;; cancel all Selector registrations 402 (let* ((keys (jdi:do-jmethod selector "keys")) 403 (iter (jdi:do-jmethod keys "iterator"))) 404 (loop while (java:jcall (java:jmethod "java.util.Iterator" "hasNext") 405 (jdi:jop-deref iter)) 406 do (java:jcall 407 (java:jmethod "java.nio.channels.SelectionKey" "cancel") 408 (java:jcall (java:jmethod "java.util.Iterator" "next") 409 (jdi:jop-deref iter))))) 410 ;; close the selector 415 (setf (state (gethash chan %wait)) 416 :READ)))))))) 417 ;; close the selector: all keys will be deregistered 411 418 (java:jcall (java:jmethod "java.nio.channels.Selector" "close") 412 419 (jdi:jop-deref selector)) 413 420 ;; make all sockets blocking again. 414 (let ((jtrue (java:make-immediate-object t :boolean))) 415 (dolist (chan channels) 421 (dolist (channel channels) 416 422 (java:jcall (java:jmethod "java.nio.channels.SelectableChannel" 417 423 "configureBlocking" 418 424 "boolean") 419 (jdi:jop-deref chan) jtrue)))))) 420 425 (jdi:jop-deref channel) 426 (java:make-immediate-object t :boolean)))))) 427 428 429 ;; 430 ;; 431 ;; 432 ;; The WAIT-LIST part 433 ;; 434 435 ;; 436 ;; Note that even though Java has the concept of the Selector class, which 437 ;; remotely looks like a wait-list, it requires the sockets to be non-blocking. 438 ;; usocket however doesn't make any such guarantees and is therefore unable to 439 ;; use the concept outside of the waiting routine itself (blergh!). 440 ;; 441 442 (defun %setup-wait-list (wl) 443 (setf (wait-list-%wait wl) 444 (make-hash-table :test #'equal :rehash-size 1.3d0))) 445 446 (defun %add-waiter (wl w) 447 (setf (gethash (jdi:jop-deref (socket w)) (wait-list-%wait wl)) 448 w)) 449 450 (defun %remove-waiter (wl w) 451 (remhash (socket w) (wait-list-%wait wl))) trunk/thirdparty/usocket/backend/clisp.lisp
r3497 r3725 1 ;;;; $Id: clisp.lisp 335 2008-04-23 21:29:50Z hhubner$2 ;;;; $URL: svn ://common-lisp.net/project/usocket/svn/usocket/branches/hans/backend/clisp.lisp $1 ;;;; $Id: clisp.lisp 412 2008-08-01 22:08:45Z ehuelsmann $ 2 ;;;; $URL: svn+ssh://common-lisp.net/project/usocket/svn/usocket/branches/0.4.x/backend/clisp.lisp $ 3 3 4 4 ;;;; See LICENSE for licensing information. … … 56 56 (signal usock-err :socket socket))))))) 57 57 58 (defun socket-connect (host port &key (element-type 'character) timeout nodelay) 58 (defun socket-connect (host port &key (element-type 'character) 59 timeout deadline (nodelay t nodelay-specified) 60 local-host local-port) 59 61 (declare (ignore nodelay)) 60 (when timeout 61 (warn "SOCKET-CONNECT timeout not supported in CLISP")) 62 (when timeout (unsupported 'timeout 'socket-connect)) 63 (when deadline (unsupported 'deadline 'socket-connect)) 64 (when nodelay-specified (unsupported 'nodelay 'socket-connect)) 65 (when (or local-host local-port) 66 (unsupported 'local-host 'socket-connect) 67 (unsupported 'local-port 'socket-connect)) 68 62 69 (let ((socket) 63 70 (hostname (host-to-hostname host))) 64 71 (with-mapped-conditions (socket) 65 72 (setf socket 73 (if timeout 74 (socket:socket-connect port hostname 75 :element-type element-type 76 :buffered t 77 :timeout timeout) 66 78 (socket:socket-connect port hostname 67 79 :element-type element-type 68 :buffered t)))80 :buffered t)))) 69 81 (make-stream-socket :socket socket 70 82 :stream socket))) ;; the socket is a stream too … … 100 112 (defmethod socket-close ((usocket usocket)) 101 113 "Close socket." 114 (when (wait-list usocket) 115 (remove-waiter (wait-list usocket) usocket)) 102 116 (with-mapped-conditions (usocket) 103 117 (close (socket usocket)))) 104 118 105 119 (defmethod socket-close ((usocket stream-server-usocket)) 120 (when (wait-list usocket) 121 (remove-waiter (wait-list usocket) usocket)) 106 122 (socket:socket-server-close (socket usocket))) 107 123 … … 131 147 132 148 133 (defmethod wait-for-input-internal (sockets &key timeout) 149 (defun %setup-wait-list (wait-list) 150 (declare (ignore wait-list))) 151 152 (defun %add-waiter (wait-list waiter) 153 (push (cons (socket waiter) NIL) (wait-list-%wait wait-list))) 154 155 (defun %remove-waiter (wait-list waiter) 156 (setf (wait-list-%wait wait-list) 157 (remove (socket waiter) (wait-list-%wait wait-list) :key #'car))) 158 159 (defmethod wait-for-input-internal (wait-list &key timeout) 134 160 (with-mapped-conditions () 135 161 (multiple-value-bind 136 162 (secs musecs) 137 163 (split-timeout (or timeout 1)) 138 (let* ((request-list (mapcar #'(lambda (x) 139 (if (stream-server-usocket-p x) 140 (socket x) 141 (list (socket x) :input))) 142 sockets)) 164 (dolist (x (wait-list-%wait wait-list)) 165 (setf (cdr x) :INPUT)) 166 (let* ((request-list (wait-list-%wait wait-list)) 143 167 (status-list (if timeout 144 168 (socket:socket-status request-list secs musecs) 145 (socket:socket-status request-list)))) 146 (remove nil 147 (mapcar #'(lambda (x y) 148 (when y x)) 149 sockets status-list)))))) 169 (socket:socket-status request-list))) 170 (sockets (wait-list-waiters wait-list))) 171 (do* ((x (pop sockets) (pop sockets)) 172 (y (pop status-list) (pop status-list))) 173 ((null x)) 174 (when (eq y :INPUT) 175 (setf (state x) :READ))) 176 wait-list)))) 150 177 151 178 152 ;;153 ;; UDP/Datagram sockets!154 ;;155 156 #+rawsock157 (progn158 159 (defun make-sockaddr_in ()160 (make-array 16 :element-type '(unsigned-byte 8) :initial-element 0))161 162 (declaim (inline fill-sockaddr_in))163 (defun fill-sockaddr_in (sockaddr_in ip port)164 (port-to-octet-buffer sockaddr_in port)165 (ip-to-octet-buffer sockaddr_in ip :start 2)166 sockaddr_in)167 168 (defun socket-create-datagram (local-port169 &key (local-host *wildcard-host*)170 remote-host171 remote-port)172 (let ((sock (rawsock:socket :inet :dgram 0))173 (lsock_addr (fill-sockaddr_in (make-sockaddr_in)174 local-host local-port))175 (rsock_addr (when remote-host176 (fill-sockaddr_in (make-sockaddr_in)177 remote-host (or remote-port178 local-port)))))179 (bind sock lsock_addr)180 (when rsock_addr181 (connect sock rsock_addr))182 (make-datagram-socket sock :connected-p (if rsock_addr t nil))))183 184 (defun socket-receive (socket buffer &key (size (length buffer)))185 "Returns the buffer, the number of octets copied into the buffer (received)186 and the address of the sender as values."187 (let* ((sock (socket socket))188 (sockaddr (when (not (connected-p socket))189 (rawsock:make-sockaddr)))190 (rv (if sockaddr191 (rawsock:recvfrom sock buffer sockaddr192 :start 0193 :end size)194 (rawsock:recv sock buffer195 :start 0196 :end size))))197 (values buffer198 rv199 (list (ip-from-octet-buffer (sockaddr-data sockaddr) 4)200 (port-from-octet-buffer (sockaddr-data sockaddr) 2)))))201 202 (defun socket-send (socket buffer &key address (size (length buffer)))203 "Returns the number of octets sent."204 (let* ((sock (socket socket))205 (sockaddr (when address206 (rawsock:make-sockaddr :INET207 (fill-sockaddr_in208 (make-sockaddr_in)209 (host-byte-order210 (second address))211 (first address)))))212 (rv (if address213 (rawsock:sendto sock buffer sockaddr214 :start 0215 :end size)216 (rawsock:send sock buffer217 :start 0218 :end size))))219 rv))220 221 (defmethod socket-close ((usocket datagram-usocket))222 (rawsock:sock-close (socket usocket)))223 224 )225 226 #-rawsock227 (progn228 (warn "This image doesn't contain the RAWSOCK package.229 To enable UDP socket support, please be sure to use the -Kfull parameter230 at startup, or to enable RAWSOCK support during compilation.")231 232 )trunk/thirdparty/usocket/backend/cmucl.lisp
r3637 r3725 1 ;;;; $Id: cmucl.lisp 335 2008-04-23 21:29:50Z hhubner$2 ;;;; $URL: svn ://common-lisp.net/project/usocket/svn/usocket/branches/hans/backend/cmucl.lisp $1 ;;;; $Id: cmucl.lisp 405 2008-07-30 19:26:46Z ehuelsmann $ 2 ;;;; $URL: svn+ssh://common-lisp.net/project/usocket/svn/usocket/branches/0.4.x/backend/cmucl.lisp $ 3 3 4 4 ;;;; See LICENSE for licensing information. … … 51 51 :condition condition)))) 52 52 53 (defun socket-connect (host port &key (element-type 'character) timeout nodelay) 53 (defun socket-connect (host port &key (element-type 'character) 54 timeout deadline (nodelay t nodelay-specified) 55 local-host local-port) 54 56 (declare (ignore nodelay)) 55 (when timeout 56 (warn "SOCKET-CONNECT timeout not supported in CMUCL")) 57 (when timeout (unsupported 'timeout 'socket-connect)) 58 (when deadline (unsupported 'deadline 'socket-connect)) 59 (when nodelay-specified (unsupported 'nodelay 'socket-connect)) 60 (when (or local-host local-port) 61 (unsupported 'local-host 'socket-connect) 62 (unsupported 'local-port 'socket-connect)) 63 57 64 (let* ((socket)) 58 65 (setf socket … … 101 108 (defmethod socket-close ((usocket stream-usocket)) 102 109 "Close socket." 110 (when (wait-list usocket) 111 (remove-waiter (wait-list usocket) usocket)) 103 112 (with-mapped-conditions (usocket) 104 113 (close (socket-stream usocket)))) … … 106 115 (defmethod socket-close ((usocket usocket)) 107 116 "Close socket." 117 (when (wait-list usocket) 118 (remove-waiter (wait-list usocket) usocket)) 108 119 (with-mapped-conditions (usocket) 109 120 (ext:close-socket (socket usocket)))) … … 166 177 (unix:unix-gethostname)) 167 178 168 (defun wait-for-input-internal (sockets &key timeout) 169 #+MP 170 (progn 171 (unless (= 1 (length sockets)) 172 (error "can't wait for multiple file descriptors with multiprocessing enabled")) 173 (mp:process-wait-until-fd-usable (socket (car sockets)) :input timeout) 174 sockets) 175 #-MP 179 (defun %setup-wait-list (wait-list) 180 (declare (ignore wait-list))) 181 182 (defun %add-waiter (wait-list waiter) 183 (push (socket waiter) (wait-list-%wait wait-list))) 184 185 (defun %remove-waiter (wait-list waiter) 186 (setf (wait-list-%wait wait-list) 187 (remove (socket waiter) (wait-list-%wait wait-list)))) 188 189 (defun wait-for-input-internal (wait-list &key timeout) 176 190 (with-mapped-conditions () 177 191 (alien:with-alien ((rfds (alien:struct unix:fd-set))) 178 192 (unix:fd-zero rfds) 179 (dolist (socket sockets)180 (unix:fd-set (socket socket)rfds))193 (dolist (socket (wait-list-%wait wait-list)) 194 (unix:fd-set socket rfds)) 181 195 (multiple-value-bind 182 196 (secs musecs) … … 184 198 (multiple-value-bind 185 199 (count err) 186 (unix:unix-fast-select (1+ (reduce #'max sockets187 :key #'socket))200 (unix:unix-fast-select (1+ (reduce #'max 201 (wait-list-%wait wait-list))) 188 202 (alien:addr rfds) nil nil 189 203 (when timeout secs) musecs) 190 204 (if (<= 0 count) 191 205 ;; process the result... 192 ( remove-if #'(lambda (x)193 (not (unix:fd-isset (socket x) rfds)))194 sockets)206 (dolist (x (wait-list-waiters wait-list)) 207 (when (unix:fd-isset (socket x) rfds) 208 (setf (state x) :READ))) 195 209 (progn 196 210 ;;###FIXME generate an error, except for EINTR trunk/thirdparty/usocket/backend/lispworks.lisp
r3497 r3725 1 ;;;; $Id: lispworks.lisp 335 2008-04-23 21:29:50Z hhubner$2 ;;;; $URL: svn ://common-lisp.net/project/usocket/svn/usocket/branches/hans/backend/lispworks.lisp $1 ;;;; $Id: lispworks.lisp 406 2008-07-30 20:56:49Z ehuelsmann $ 2 ;;;; $URL: svn+ssh://common-lisp.net/project/usocket/svn/usocket/branches/0.4.x/backend/lispworks.lisp $ 3 3 4 4 ;;;; See LICENSE for licensing information. … … 74 74 (raise-usock-err errno socket condition))))) 75 75 76 (defun socket-connect (host port &key (element-type 'base-char) timeout nodelay) 77 (declare (ignore nodelay)) 78 (when timeout 79 (warn "SOCKET-CONNECT timeout not supported in Lispworks")) 76 (defun socket-connect (host port &key (element-type 'base-char) 77 timeout deadline (nodelay t nodelay-specified) 78 local-host local-port) 79 (declare (ignorable nodelay)) 80 (when timeout (unimplemented 'timeout 'socket-connect)) 81 (when deadline (unsupported 'deadline 'socket-connect :minimum "LispWorks 5.1")) 82 83 #+(and (not lispworks4) (not lispworks5.0)) 84 (when nodelay-specified (unimplemented 'nodelay 'socket-connect)) 85 #+lispworks4 86 (when (or local-host local-port) 87 (unsupported 'local-host 'socket-connect :minimum "LispWorks 5.0+ (verified)") 88 (unsupported 'local-port 'socket-connect :minimum "LispWorks 5.0+ (verified)")) 89 80 90 (let ((hostname (host-to-hostname host)) 81 91 (stream)) … … 83 93 (with-mapped-conditions () 84 94 (comm:open-tcp-stream hostname port 85 :element-type element-type))) 95 :element-type element-type 96 #-lispworks4 #-lispworks4 97 #-lispworks4 #-lispworks4 98 :local-address (when local-host (host-to-hostname local-host)) 99 :local-port local-port 100 #+(and (not lispworks4) (not lispworks5.0)) 101 #+(and (not lispworks4) (not lispworks5.0)) 102 :nodelay nodelay))) 86 103 (if stream 87 104 (make-stream-socket :socket (comm:socket-stream-socket stream) … … 94 111 (backlog 5) 95 112 (element-type 'base-char)) 113 #+lispworks4.1 114 (unsupported 'host 'socket-listen :minimum "LispWorks 4.0 or newer than 4.1") 115 #+lispworks4.1 116 (unsupported 'backlog 'socket-listen :minimum "LispWorks 4.0 or newer than 4.1") 117 96 118 (let* ((reuseaddress (if reuse-address-supplied-p reuse-address reuseaddress)) 97 119 (comm::*use_so_reuseaddr* reuseaddress) … … 121 143 (defmethod socket-close ((usocket stream-usocket)) 122 144 "Close socket." 145 (when (wait-list usocket) 146 (remove-waiter (wait-list usocket) usocket)) 123 147 (close (socket-stream usocket))) 124 148 125 149 (defmethod socket-close ((usocket usocket)) 150 (when (wait-list usocket) 151 (remove-waiter (wait-list usocket) usocket)) 126 152 (with-mapped-conditions (usocket) 127 153 (comm::close-socket (socket usocket)))) … … 161 187 (defun usocket-listen (usocket) 162 188 (if (stream-usocket-p usocket) 163 (when (listen (socket usocket))189 (when (listen (socket-stream usocket)) 164 190 usocket) 165 191 (when (comm::socket-listen (socket usocket)) … … 173 199 174 200 #-win32 175 (defun wait-for-input-internal (sockets &key timeout) 201 (progn 202 203 (defun %setup-wait-list (wait-list) 204 (declare (ignore wait-list))) 205 206 (defun %add-waiter (wait-list waiter) 207 (declare (ignore wait-list waiter))) 208 209 (defun %remove-waiter (wait-list waiter) 210 (declare (ignore wait-list waiter))) 211 212 (defun wait-for-input-internal (wait-list &key timeout) 176 213 (with-mapped-conditions () 177 214 ;; unfortunately, it's impossible to share code between 178 215 ;; non-win32 and win32 platforms... 179 216 ;; Can we have a sane -pref. complete [UDP!?]- API next time, please? 180 (mapcar #'mp:notice-fd sockets181 :key #'os-socket-handle)217 (dolist (x (wait-list-waiters wait-list)) 218 (mp:notice-fd (os-socket-handle x))) 182 219 (mp:process-wait-with-timeout "Waiting for a socket to become active" 183 220 (truncate timeout) 184 221 #'(lambda (socks) 185 (some #'usocket-listen socks)) 186 sockets) 187 (mapcar #'mp:unnotice-fd sockets 188 :key #'os-socket-handle) 189 (remove nil (mapcar #'usocket-listen sockets)))) 222 (let (rv) 223 (dolist (x socks rv) 224 (when (usocket-listen x) 225 (setf (state x) :READ 226 rv t))))) 227 (wait-list-waiters wait-list)) 228 (dolist (x (wait-list-waiters wait-list)) 229 (mp:unnotice-fd (os-socket-handle x))) 230 wait-list))) 190 231 191 232 … … 232 273 (defconstant fionread 1074030207) 233 274 275 276 ;; Note: 277 ;; 278 ;; If special finalization has to occur for a given 279 ;; system resource (handle), an associated object should 280 ;; be created. A special cleanup action should be added 281 ;; to the system and a special cleanup action should 282 ;; be flagged on all objects created for resources like it 283 ;; 284 ;; We have 2 functions to do so: 285 ;; * hcl:add-special-free-action (function-symbol) 286 ;; * hcl:flag-special-free-action (object) 287 ;; 288 ;; Note that the special free action will be called on all 289 ;; objects which have been flagged for special free, so be 290 ;; sure to check for the right argument type! 291 234 292 (fli:define-foreign-type ws-socket () '(:unsigned :int)) 235 293 (fli:define-foreign-type win32-handle () '(:unsigned :int)) … … 276 334 ;; Now that we have access to the system calls, this is the plan: 277 335 278 ;; 1. Receive a list of sockets to listen to336 ;; 1. Receive a wait-list with associated sockets to wait for 279 337 ;; 2. Add all those sockets to an event handle 280 338 ;; 3. Listen for an event on that handle (we have a LispWorks system:: internal for that) … … 296 354 0)))) 297 355 298 (defun add-socket-to-event (socket event-object)299 (let ((events (etypecase socket300 (stream-server-usocket (logior fd-connect fd-accept fd-close))301 (stream-usocket (logior fd-connect fd-read fd-oob fd-close)))))302 (maybe-wsa-error303 (wsa-event-select (os-socket-handle socket) event-object events)304 socket)))305 306 356 (defun socket-ready-p (socket) 307 357 (if (typep socket 'stream-usocket) … … 312 362 (notany #'socket-ready-p sockets)) 313 363 314 (defun wait-for-input-internal (sockets &key timeout) 315 (let ((event-object (wsa-event-create))) 316 (unwind-protect 317 (progn 318 (when (waiting-required sockets) 319 (dolist (socket sockets) 320 (add-socket-to-event socket event-object)) 321 (system:wait-for-single-object event-object 364 (defun wait-for-input-internal (wait-list &key timeout) 365 (when (waiting-required (wait-list-waiters wait-list)) 366 (system:wait-for-single-object (wait-list-%wait wait-list) 322 367 "Waiting for socket activity" timeout)) 323 (update-ready-slots sockets) 324 (sockets-ready sockets)) 325 (wsa-event-close event-object)))) 368 (update-ready-and-state-slots (wait-list-waiters wait-list))) 369 326 370 327 371 (defun map-network-events (func network-events) … … 330 374 (unless (zerop event-map) 331 375 (dotimes (i fd-max-events) 332 (unless (zerop (ldb (byte 1 i) event-map)) 376 (unless (zerop (ldb (byte 1 i) event-map)) ;;### could be faster with ash and logand? 333 377 (funcall func (fli:foreign-aref error-array i))))))) 334 378 335 (defun update-ready- slots (sockets)379 (defun update-ready-and-state-slots (sockets) 336 380 (dolist (socket sockets) 337 (unless (or (stream-usocket-p socket) ;; no need to check status for streams 338 (%ready-p socket)) ;; and sockets already marked ready 381 (if (or (and (stream-usocket-p socket) 382 (listen (socket-stream socket))) 383 (%ready-p socket)) 384 (setf (state socket) :READ) 339 385 (multiple-value-bind 340 386 (rv network-events) … … 343 389 (map-network-events #'(lambda (err-code) 344 390 (if (zerop err-code) 345 (setf (%ready-p socket) t) 391 (setf (%ready-p socket) t 392 (state socket) :READ) 346 393 (raise-usock-err err-code socket))) 347 394 network-events) 348 395 (maybe-wsa-error rv socket)))))) 349 396 350 (defun sockets-ready (sockets) 351 (remove-if-not #'socket-ready-p sockets)) 397 398 399 ;; The wait-list part 400 401 (defun free-wait-list (wl) 402 (when (wait-list-p wl) 403 (unless (null (wait-list-%wait wl)) 404 (wsa-event-close (wait-list-%wait wl))))) 405 406 (hcl:add-special-free-action 'free-wait-list) 407 408 (defun %setup-wait-list (wait-list) 409 (hcl:flag-special-free-action wait-list) 410 (setf (wait-list-%wait wait-list) (wsa-event-create))) 411 412 (defun %add-waiter (wait-list waiter) 413 (let ((events (etypecase waiter 414 (stream-server-usocket (logior fd-connect fd-accept fd-close)) 415 (stream-usocket (logior fd-connect fd-read fd-oob fd-close))))) 416 (maybe-wsa-error 417 (wsa-event-select (os-socket-handle waiter) (wait-list-%wait wait-list) events) 418 waiter))) 419 420 (defun %remove-waiter (wait-list waiter) 421 (maybe-wsa-error 422 (wsa-event-select (os-socket-handle waiter) (wait-list-%wait wait-list) 0) 423 waiter)) 352 424 353 425 );; end of WIN32-block trunk/thirdparty/usocket/backend/openmcl.lisp
r3495 r3725 1 ;;;; $Id: openmcl.lisp 335 2008-04-23 21:29:50Z hhubner$2 ;;;; $URL: svn ://common-lisp.net/project/usocket/svn/usocket/branches/hans/backend/openmcl.lisp $1 ;;;; $Id: openmcl.lisp 405 2008-07-30 19:26:46Z ehuelsmann $ 2 ;;;; $URL: svn+ssh://common-lisp.net/project/usocket/svn/usocket/branches/0.4.x/backend/openmcl.lisp $ 3 3 4 4 ;;;; See LICENSE for licensing information. … … 33 33 (ccl::rletZ ((tv :timeval)) 34 34 (ccl::ticks-to-timeval ticks-to-wait tv) 35 ;;### The trickery below can be moved to the wait-list now... 35 36 (ccl::%stack-block ((infds ccl::*fd-set-size*)) 36 37 (ccl::fd-zero infds) 37 38 (let ((max-fd -1)) 38 39 (dolist (sock sockets) 39 (let ((fd (openmcl-socket:socket-os-fd sock)))40 (let ((fd (openmcl-socket:socket-os-fd (socket sock)))) 40 41 (setf max-fd (max max-fd fd)) 41 42 &
