Changeset 3728
- Timestamp:
- 08/07/08 22:06:50 (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) (9 diffs)
- trunk/thirdparty/usocket/backend/clisp.lisp (modified) (5 diffs)
- trunk/thirdparty/usocket/backend/cmucl.lisp (modified) (6 diffs)
- trunk/thirdparty/usocket/backend/lispworks.lisp (modified) (12 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) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/thirdparty/usocket/Makefile
r3727 r3728 1 1 # $Id: Makefile 80 2006-02-12 10:09:49Z ehuelsmann $ 2 # $URL: svn +ssh://common-lisp.net/project/usocket/svn/usocket/trunk/Makefile $2 # $URL: svn://common-lisp.net/project/usocket/svn/usocket/branches/hans/Makefile $ 3 3 4 4 clean: trunk/thirdparty/usocket/README
r3727 r3728 1 1 -*- text -*- 2 2 3 $Id: README 249 2007-05-20 14:16:12Z ehuelsmann$3 $Id: README 334 2008-04-23 21:24:15Z hhubner $ 4 4 5 5 Content … … 96 96 97 97 98 99 100 98 Errors: 101 99 - address-in-use-error trunk/thirdparty/usocket/TODO
r3727 r3728 2 2 - Implement wait-for-input-internal for 3 3 * SBCL Win32 4 * LispWorks Win32 4 5 5 6 - Implement errors for (the alien interface code of) trunk/thirdparty/usocket/backend/allegro.lisp
r3727 r3728 1 ;;;; $Id: allegro.lisp 405 2008-07-30 19:26:46Z ehuelsmann$2 ;;;; $URL: svn +ssh://common-lisp.net/project/usocket/svn/usocket/trunk/backend/allegro.lisp $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 $ 3 3 4 4 ;;;; See LICENSE for licensing information. … … 50 50 :binary)) 51 51 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 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")) 59 56 (let ((socket)) 60 57 (setf socket 61 58 (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)) 70 (socket:make-socket :remote-host (host-to-hostname host) 71 :remote-port port 72 :local-host local-host 73 :local-port local-port 74 :format (to-format element-type) 75 :nodelay nodelay)))) 59 (socket:make-socket :remote-host (host-to-hostname host) 60 :remote-port port 61 :format (to-format element-type)))) 76 62 (make-stream-socket :socket socket :stream socket))) 77 63 … … 81 67 (defmethod socket-close ((usocket usocket)) 82 68 "Close socket." 83 (when (wait-list usocket)84 (remove-waiter (wait-list usocket) usocket))85 69 (with-mapped-conditions (usocket) 86 70 (close (socket usocket)))) … … 147 131 (host-to-hostname name)))))) 148 132 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) 133 (defun wait-for-input-internal (sockets &key timeout) 160 134 (with-mapped-conditions () 161 135 (let ((active-internal-sockets 162 136 (if timeout 163 (mp:wait-for-input-available ( wait-list-%wait wait-list)137 (mp:wait-for-input-available (mapcar #'socket sockets) 164 138 :timeout timeout) 165 (mp:wait-for-input-available ( wait-list-%wait wait-list)))))139 (mp:wait-for-input-available (mapcar #'socket sockets))))) 166 140 ;; this is quadratic, but hey, the active-internal-sockets 167 141 ;; list is very short and it's only quadratic in the length of that one. 168 142 ;; When I have more time I could recode it to something of linear 169 143 ;; complexity. 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))) 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)))) trunk/thirdparty/usocket/backend/armedbear.lisp
r3727 r3728 1 ;;;; $Id: armedbear.lisp 409 2008-07-31 05:50:06Z ehuelsmann$2 ;;;; $URL: svn +ssh://common-lisp.net/project/usocket/svn/usocket/trunk/backend/armedbear.lisp $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 $ 3 3 4 4 ;;;; See LICENSE for licensing information. … … 89 89 (java:jclass-name (jop-class instance))))) 90 90 91 (declaim (inline jop-deref))92 91 (defun jop-deref (instance) 93 92 (if (java-object-proxy-p instance) … … 187 186 (error (error 'unknown-error :socket socket :real-error condition)))) 188 187 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 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")) 197 192 (let ((usock)) 198 193 (with-mapped-conditions (usock) 199 194 (let* ((sock-addr (jdi:jcoerce 200 195 (jdi:do-jnew-call "java.net.InetSocketAddress" 201 (host-to-hostname host)202 (jdi:jcoerce port :int))196 (host-to-hostname host) 197 (jdi:jcoerce port :int)) 203 198 "java.net.SocketAddress")) 204 199 (jchan (jdi:do-jstatic-call "java.nio.channels.SocketChannel" 205 "open" sock-addr))200 "open" sock-addr)) 206 201 (sock (jdi:do-jmethod-call jchan "socket"))) 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)))) 215 (setf usock 216 (make-stream-socket 217 :socket jchan 218 :stream (ext:get-socket-stream (jdi:jop-deref sock) 219 :element-type element-type))))))) 202 (describe sock) 203 (setf usock 204 (make-stream-socket 205 :socket jchan 206 :stream (ext:get-socket-stream (jdi:jop-deref sock) 207 :element-type element-type))))))) 220 208 221 209 (defun socket-listen (host port … … 261 249 262 250 (defmethod socket-close ((usocket usocket)) 263 (when (wait-list usocket)264 (remove-waiter (wait-list usocket) usocket))265 251 (with-mapped-conditions (usocket) 266 252 (jdi:do-jmethod (socket usocket) "close"))) … … 270 256 ;; its buffers *and* closes the socket. 271 257 (defmethod socket-close ((usocket stream-usocket)) 272 (when (wait-list usocket)273 (remove-waiter (wait-list usocket) usocket))274 258 (with-mapped-conditions (usocket) 275 259 (close (socket-stream usocket)))) 276 260 277 261 (defmethod get-local-address ((usocket usocket)) 278 (dotted-quad-to-vector-quad (ext:socket-local-address 279 (jdi:jop-deref 280 (jdi:do-jmethod-call (socket usocket) 281 "socket"))))) 262 (dotted-quad-to-vector-quad (ext:socket-local-address (socket usocket)))) 282 263 283 264 (defmethod get-peer-address ((usocket stream-usocket)) 284 (dotted-quad-to-vector-quad (ext:socket-peer-address 285 (jdi:jop-deref 286 (jdi:do-jmethod-call (socket usocket) 287 "socket"))))) 265 (dotted-quad-to-vector-quad (ext:socket-peer-address (socket usocket)))) 288 266 289 267 (defmethod get-local-port ((usocket usocket)) 290 (ext:socket-local-port (jdi:jop-deref 291 (jdi:do-jmethod-call (socket usocket) "socket")))) 268 (ext:socket-local-port (socket usocket))) 292 269 293 270 (defmethod get-peer-port ((usocket stream-usocket)) 294 (ext:socket-peer-port (jdi:jop-deref 295 (jdi:do-jmethod-call (socket usocket) "socket")))) 271 (ext:socket-peer-port (socket usocket))) 296 272 297 273 (defmethod get-local-name ((usocket usocket)) … … 377 353 "java.nio.channels.DatagramChannel"))) 378 354 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))) 355 (defun wait-for-input-internal (sockets &key timeout) 356 (let* ((ops (logior (op-read) (op-accept))) 382 357 (selector (jdi:do-jstatic "java.nio.channels.Selector" "open")) 383 358 (channels (mapcar #'socket sockets))) 384 359 (unwind-protect 385 360 (with-mapped-conditions () 386 (let ((sel (jdi:jop-deref selector))) 361 (let ((jfalse (java:make-immediate-object nil :boolean)) 362 (sel (jdi:jop-deref selector))) 387 363 (dolist (channel channels) 388 364 (let ((chan (jdi:jop-deref channel))) … … 390 366 "configureBlocking" 391 367 "boolean") 392 chan (java:make-immediate-object nil :boolean))368 chan jfalse) 393 369 (java:jcall (java:jmethod "java.nio.channels.SelectableChannel" 394 370 "register" … … 404 380 (let* ((selkeys (jdi:do-jmethod selector "selectedKeys")) 405 381 (selkey-iterator (jdi:do-jmethod selkeys "iterator")) 406 (%wait (wait-list-%wait wait-list)))382 ready-sockets) 407 383 (loop while (java:jcall 408 384 (java:jmethod "java.util.Iterator" "hasNext") … … 413 389 (chan (jdi:jop-deref 414 390 (jdi:do-jmethod key "channel")))) 415 (setf (state (gethash chan %wait)) 416 :READ)))))))) 417 ;; close the selector: all keys will be deregistered 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 418 411 (java:jcall (java:jmethod "java.nio.channels.Selector" "close") 419 412 (jdi:jop-deref selector)) 420 413 ;; make all sockets blocking again. 421 (dolist (channel channels) 422 (java:jcall (java:jmethod "java.nio.channels.SelectableChannel" 423 "configureBlocking" 424 "boolean") 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))) 414 (let ((jtrue (java:make-immediate-object t :boolean))) 415 (dolist (chan channels) 416 (java:jcall (java:jmethod "java.nio.channels.SelectableChannel" 417 "configureBlocking" 418 "boolean") 419 (jdi:jop-deref chan) jtrue)))))) 420 trunk/thirdparty/usocket/backend/clisp.lisp
r3727 r3728 1 ;;;; $Id: clisp.lisp 405 2008-07-30 19:26:46Z ehuelsmann$2 ;;;; $URL: svn +ssh://common-lisp.net/project/usocket/svn/usocket/trunk/backend/clisp.lisp $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 $ 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) 59 timeout deadline (nodelay t nodelay-specified) 60 local-host local-port) 58 (defun socket-connect (host port &key (element-type 'character) timeout nodelay) 61 59 (declare (ignore nodelay)) 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 60 (when timeout 61 (warn "SOCKET-CONNECT timeout not supported in CLISP")) 69 62 (let ((socket) 70 63 (hostname (host-to-hostname host))) 71 64 (with-mapped-conditions (socket) 72 (setf socket 73 (if timeout 74 (socket:socket-connect port hostname 75 :element-type element-type 76 :buffered t 77 :timeout timeout) 78 (socket:socket-connect port hostname 79 :element-type element-type 80 :buffered t)))) 65 (setf socket 66 (socket:socket-connect port hostname 67 :element-type element-type 68 :buffered t))) 81 69 (make-stream-socket :socket socket 82 70 :stream socket))) ;; the socket is a stream too … … 112 100 (defmethod socket-close ((usocket usocket)) 113 101 "Close socket." 114 (when (wait-list usocket)115 (remove-waiter (wait-list usocket) usocket))116 102 (with-mapped-conditions (usocket) 117 103 (close (socket usocket)))) 118 104 119 105 (defmethod socket-close ((usocket stream-server-usocket)) 120 (when (wait-list usocket)121 (remove-waiter (wait-list usocket) usocket))122 106 (socket:socket-server-close (socket usocket))) 123 107 … … 147 131 148 132 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) 133 (defmethod wait-for-input-internal (sockets &key timeout) 160 134 (with-mapped-conditions () 161 135 (multiple-value-bind 162 136 (secs musecs) 163 137 (split-timeout (or timeout 1)) 164 (dolist (x (wait-list-%wait wait-list)) 165 (setf (cdr x) :INPUT)) 166 (let* ((request-list (wait-list-%wait wait-list)) 138 (let* ((request-list (mapcar #'(lambda (x) 139 (if (stream-server-usocket-p x) 140 (socket x) 141 (list (socket x) :input))) 142 sockets)) 167 143 (status-list (if timeout 168 144 (socket:socket-status request-list secs musecs) 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)))) 145 (socket:socket-status request-list)))) 146 (remove nil 147 (mapcar #'(lambda (x y) 148 (when y x)) 149 sockets status-list)))))) 177 150 178 151 … … 247 220 248 221 (defmethod socket-close ((usocket datagram-usocket)) 249 (when (wait-list usocket)250 (remove-waiter (wait-list usocket) usocket))251 222 (rawsock:sock-close (socket usocket))) 252 223 trunk/thirdparty/usocket/backend/cmucl.lisp
r3727 r3728 1 ;;;; $Id: cmucl.lisp 405 2008-07-30 19:26:46Z ehuelsmann$2 ;;;; $URL: svn +ssh://common-lisp.net/project/usocket/svn/usocket/trunk/backend/cmucl.lisp $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 $ 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) 54 timeout deadline (nodelay t nodelay-specified) 55 local-host local-port) 53 (defun socket-connect (host port &key (element-type 'character) timeout nodelay) 56 54 (declare (ignore nodelay)) 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 55 (when timeout 56 (warn "SOCKET-CONNECT timeout not supported in CMUCL")) 64 57 (let* ((socket)) 65 58 (setf socket … … 108 101 (defmethod socket-close ((usocket stream-usocket)) 109 102 "Close socket." 110 (when (wait-list usocket)111 (remove-waiter (wait-list usocket) usocket))112 103 (with-mapped-conditions (usocket) 113 104 (close (socket-stream usocket)))) … … 115 106 (defmethod socket-close ((usocket usocket)) 116 107 "Close socket." 117 (when (wait-list usocket)118 (remove-waiter (wait-list usocket) usocket))119 108 (with-mapped-conditions (usocket) 120 109 (ext:close-socket (socket usocket)))) … … 177 166 (unix:unix-gethostname)) 178 167 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) 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 190 176 (with-mapped-conditions () 191 177 (alien:with-alien ((rfds (alien:struct unix:fd-set))) 192 178 (unix:fd-zero rfds) 193 (dolist (socket (wait-list-%wait wait-list))194 (unix:fd-set socketrfds))179 (dolist (socket sockets) 180 (unix:fd-set (socket socket) rfds)) 195 181 (multiple-value-bind 196 182 (secs musecs) … … 198 184 (multiple-value-bind 199 185 (count err) 200 (unix:unix-fast-select (1+ (reduce #'max 201 (wait-list-%wait wait-list)))186 (unix:unix-fast-select (1+ (reduce #'max sockets 187 :key #'socket)) 202 188 (alien:addr rfds) nil nil 203 189 (when timeout secs) musecs) 204 190 (if (<= 0 count) 205 191 ;; process the result... 206 ( dolist (x (wait-list-waiters wait-list))207 (when (unix:fd-isset (socket x) rfds)208 (setf (state x) :READ)))192 (remove-if #'(lambda (x) 193 (not (unix:fd-isset (socket x) rfds))) 194 sockets) 209 195 (progn 210 196 ;;###FIXME generate an error, except for EINTR trunk/thirdparty/usocket/backend/lispworks.lisp
r3727 r3728 1 ;;;; $Id: lispworks.lisp 406 2008-07-30 20:56:49Z ehuelsmann$2 ;;;; $URL: svn +ssh://common-lisp.net/project/usocket/svn/usocket/trunk/backend/lispworks.lisp $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 $ 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) 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 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")) 90 80 (let ((hostname (host-to-hostname host)) 91 81 (stream)) … … 93 83 (with-mapped-conditions () 94 84 (comm:open-tcp-stream hostname port 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))) 85 :element-type element-type))) 103 86 (if stream 104 87 (make-stream-socket :socket (comm:socket-stream-socket stream) … … 111 94 (backlog 5) 112 95 (element-type 'base-char)) 113 #+lispworks4.1114 (unsupported 'host 'socket-listen :minimum "LispWorks 4.0 or newer than 4.1")115 #+lispworks4.1116 (unsupported 'backlog 'socket-listen :minimum "LispWorks 4.0 or newer than 4.1")117 118 96 (let* ((reuseaddress (if reuse-address-supplied-p reuse-address reuseaddress)) 119 97 (comm::*use_so_reuseaddr* reuseaddress) … … 143 121 (defmethod socket-close ((usocket stream-usocket)) 144 122 "Close socket." 145 (when (wait-list usocket)146 (remove-waiter (wait-list usocket) usocket))147 123 (close (socket-stream usocket))) 148 124 149 125 (defmethod socket-close ((usocket usocket)) 150 (when (wait-list usocket)151 (remove-waiter (wait-list usocket) usocket))152 126 (with-mapped-conditions (usocket) 153 127 (comm::close-socket (socket usocket)))) … … 187 161 (defun usocket-listen (usocket) 188 162 (if (stream-usocket-p usocket) 189 (when (listen (socket -streamusocket))163 (when (listen (socket usocket)) 190 164 usocket) 191 165 (when (comm::socket-listen (socket usocket)) … … 199 173 200 174 #-win32 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) 213 (with-mapped-conditions () 214 ;; unfortunately, it's impossible to share code between 215 ;; non-win32 and win32 platforms... 216 ;; Can we have a sane -pref. complete [UDP!?]- API next time, please? 217 (dolist (x (wait-list-waiters wait-list)) 218 (mp:notice-fd (os-socket-handle x))) 219 (mp:process-wait-with-timeout "Waiting for a socket to become active" 220 (truncate timeout) 221 #'(lambda (socks) 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))) 175 (defun wait-for-input-internal (sockets &key timeout) 176 (with-mapped-conditions () 177 ;; unfortunately, it's impossible to share code between 178 ;; non-win32 and win32 platforms... 179 ;; Can we have a sane -pref. complete [UDP!?]- API next time, please? 180 (mapcar #'mp:notice-fd sockets 181 :key #'os-socket-handle) 182 (mp:process-wait-with-timeout "Waiting for a socket to become active" 183 (truncate timeout) 184 #'(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)))) 231 190 232 191 … … 273 232 (defconstant fionread 1074030207) 274 233 275 276 ;; Note:277 ;;278 ;; If special finalization has to occur for a given279 ;; system resource (handle), an associated object should280 ;; be created. A special cleanup action should be added281 ;; to the system and a special cleanup action should282 ;; be flagged on all objects created for resources like it283 ;;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 all289 ;; objects which have been flagged for special free, so be290 ;; sure to check for the right argument type!291 292 234 (fli:define-foreign-type ws-socket () '(:unsigned :int)) 293 235 (fli:define-foreign-type win32-handle () '(:unsigned :int)) … … 334 276 ;; Now that we have access to the system calls, this is the plan: 335 277 336 ;; 1. Receive a wait-list with associated sockets to wait for278 ;; 1. Receive a list of sockets to listen to 337 279 ;; 2. Add all those sockets to an event handle 338 280 ;; 3. Listen for an event on that handle (we have a LispWorks system:: internal for that) … … 354 296 0)))) 355 297 298 (defun add-socket-to-event (socket event-object) 299 (let ((events (etypecase socket 300 (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-error 303 (wsa-event-select (os-socket-handle socket) event-object events) 304 socket))) 305 356 306 (defun socket-ready-p (socket) 357 307 (if (typep socket 'stream-usocket) … … 362 312 (notany #'socket-ready-p sockets)) 363 313 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) 367 "Waiting for socket activity" timeout)) 368 (update-ready-and-state-slots (wait-list-waiters wait-list))) 369 370 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 322 "Waiting for socket activity" timeout)) 323 (update-ready-slots sockets) 324 (sockets-ready sockets)) 325 (wsa-event-close event-object)))) 326 371 327 (defun map-network-events (func network-events) 372 328 (let ((event-map (fli:foreign-slot-value network-events 'network-events)) … … 374 330 (unless (zerop event-map) 375 331 (dotimes (i fd-max-events) 376 (unless (zerop (ldb (byte 1 i) event-map)) ;;### could be faster with ash and logand?332 (unless (zerop (ldb (byte 1 i) event-map)) 377 333 (funcall func (fli:foreign-aref error-array i))))))) 378 334 379 (defun update-ready- and-state-slots (sockets)335 (defun update-ready-slots (sockets) 380 336 (dolist (socket sockets) 381 (if (or (and (stream-usocket-p socket) 382 (listen (socket-stream socket))) 383 (%ready-p socket)) 384 (setf (state socket) :READ) 385 (multiple-value-bind 386 (rv network-events) 387 (wsa-enum-network-events (os-socket-handle socket) 0 t) 388 (if (zerop rv) 337 (unless (or (stream-usocket-p socket) ;; no need to check status for streams 338 (%ready-p socket)) ;; and sockets already marked ready 339 (multiple-value-bind 340 (rv network-events) 341 (wsa-enum-network-events (os-socket-handle socket) 0 t) 342 (if (zerop rv) 389 343 (map-network-events #'(lambda (err-code) 390 344 (if (zerop err-code) 391 (setf (%ready-p socket) t 392 (state socket) :READ) 345 (setf (%ready-p socket) t) 393 346 (raise-usock-err err-code socket))) 394 347 network-events) 395 348 (maybe-wsa-error rv socket)))))) 396 349 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)) 350 (defun sockets-ready (sockets) 351 (remove-if-not #'socket-ready-p sockets)) 424 352 425 353 );; end of WIN32-block trunk/thirdparty/usocket/backend/openmcl.lisp
r3727 r3728 1 ;;;; $Id: openmcl.lisp 414 2008-08-07 18:50:26Z ehuelsmann$2 ;;;; $URL: svn +ssh://common-lisp.net/project/usocket/svn/usocket/trunk/backend/openmcl.lisp $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 $ 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...36 35 (ccl::%stack-block ((infds ccl::*fd-set-size*)) 37 36 (ccl::fd-zero infds) 38 37 (let ((max-fd -1)) 39 38 (dolist (sock sockets) 40 (let ((fd (openmcl-socket:socket-os-fd (socket sock))))39 (let ((fd (openmcl-socket:socket-os-fd sock))) 41 40 (setf max-fd (max max-fd fd)) 42 41 (ccl::fd-set fd infds))) … … 45 44 (if ticks-to-wait tv (ccl::%null-ptr))))) 46 45 (when (> res 0) 47 (dolist (x sockets) 48 (when (ccl::fd-is-set (openmcl-socket:socket-os-fd (socket x)) 49 infds) 50 (setf (state x) :READ)))) 51 sockets))))) 46 (remove-if #'(lambda (x) 47 (not (ccl::fd-is-set (openmcl-socket:socket-os-fd x) 48 infds))) 49 sockets))))))) 52 50 53 51 (defun raise-error-from-id (condition-id socket real-condition) … … 75 73 :binary)) 76 74 77 (defun socket-connect (host port &key (element-type 'character) timeout deadline nodelay 78 local-host local-port) 75 (defun socket-connect (host port &key (element-type 'character) timeout deadline nodelay) 79 76 (with-mapped-conditions () 80 77 (let ((mcl-sock 81 78 (openmcl-socket:make-socket :remote-host (host-to-hostname host) 82 79 :remote-port port 83 :local-host (when local-host (host-to-hostname local-host))84 :local-port local-port85 80 :format (to-format element-type) 86 81 :deadline deadline … … 118 113 ;; by the same object. 119 114 (defmethod socket-
