Changeset 3727

Show
Ignore:
Timestamp:
08/07/08 21:30:29 (4 months ago)
Author:
hans
Message:

retry with fixed usocket-0.4.x

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/thirdparty/usocket/Makefile

    r3726 r3727  
    11# $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/trunk/Makefile $ 
    33 
    44clean: 
  • trunk/thirdparty/usocket/README

    r3726 r3727  
    11                                                                -*- text -*- 
    22 
    3 $Id: README 334 2008-04-23 21:24:15Z hhubner
     3$Id: README 249 2007-05-20 14:16:12Z ehuelsmann
    44 
    55Content 
     
    9696 
    9797 
     98 
     99 
    98100Errors: 
    99101 - address-in-use-error 
  • trunk/thirdparty/usocket/TODO

    r3726 r3727  
    22- Implement wait-for-input-internal for 
    33    * SBCL Win32 
    4     * LispWorks Win32 
    54 
    65- Implement errors for (the alien interface code of) 
  • trunk/thirdparty/usocket/backend/allegro.lisp

    r3726 r3727  
    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/trunk/backend/allegro.lisp $ 
    33 
    44;;;; See LICENSE for licensing information. 
     
    5050    :binary)) 
    5151 
    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 
    5659  (let ((socket)) 
    5760    (setf socket 
    5861          (with-mapped-conditions (socket) 
    59              (socket:make-socket :remote-host (host-to-hostname host) 
    60                                  :remote-port port 
    61                                  :format (to-format element-type)))) 
     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)))) 
    6276    (make-stream-socket :socket socket :stream socket))) 
    6377 
     
    6781(defmethod socket-close ((usocket usocket)) 
    6882  "Close socket." 
     83  (when (wait-list usocket) 
     84     (remove-waiter (wait-list usocket) usocket)) 
    6985  (with-mapped-conditions (usocket) 
    7086    (close (socket usocket)))) 
     
    131147                               (host-to-hostname name)))))) 
    132148 
    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) 
    134160  (with-mapped-conditions () 
    135161    (let ((active-internal-sockets 
    136162           (if timeout 
    137                (mp:wait-for-input-available (mapcar #'socket sockets
     163               (mp:wait-for-input-available (wait-list-%wait wait-list
    138164                                            :timeout timeout) 
    139              (mp:wait-for-input-available (mapcar #'socket sockets))))) 
     165             (mp:wait-for-input-available (wait-list-%wait wait-list))))) 
    140166      ;; this is quadratic, but hey, the active-internal-sockets 
    141167      ;; list is very short and it's only quadratic in the length of that one. 
    142168      ;; When I have more time I could recode it to something of linear 
    143169      ;; 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

    r3726 r3727  
    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/trunk/backend/armedbear.lisp $ 
    33 
    44;;;; See LICENSE for licensing information. 
     
    8989    (java:jclass-name (jop-class instance))))) 
    9090 
     91(declaim (inline jop-deref)) 
    9192(defun jop-deref (instance) 
    9293  (if (java-object-proxy-p instance) 
     
    186187    (error (error 'unknown-error :socket socket :real-error condition)))) 
    187188 
    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 
    192197  (let ((usock)) 
    193198    (with-mapped-conditions (usock) 
    194199      (let* ((sock-addr (jdi:jcoerce 
    195200                         (jdi:do-jnew-call "java.net.InetSocketAddress" 
    196                                            (host-to-hostname host) 
    197                                            (jdi:jcoerce port :int)) 
     201                           (host-to-hostname host) 
     202                           (jdi:jcoerce port :int)) 
    198203                         "java.net.SocketAddress")) 
    199204             (jchan (jdi:do-jstatic-call "java.nio.channels.SocketChannel" 
    200                                          "open" sock-addr)) 
     205                      "open" sock-addr)) 
    201206             (sock (jdi:do-jmethod-call jchan "socket"))) 
    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))))))) 
     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))))))) 
    208220 
    209221(defun socket-listen (host port 
     
    249261 
    250262(defmethod socket-close ((usocket usocket)) 
     263  (when (wait-list usocket) 
     264     (remove-waiter (wait-list usocket) usocket)) 
    251265  (with-mapped-conditions (usocket) 
    252266    (jdi:do-jmethod (socket usocket) "close"))) 
     
    256270;; its buffers *and* closes the socket. 
    257271(defmethod socket-close ((usocket stream-usocket)) 
     272  (when (wait-list usocket) 
     273     (remove-waiter (wait-list usocket) usocket)) 
    258274  (with-mapped-conditions (usocket) 
    259275    (close (socket-stream usocket)))) 
    260276 
    261277(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"))))) 
    263282 
    264283(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"))))) 
    266288 
    267289(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")))) 
    269292 
    270293(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")))) 
    272296 
    273297(defmethod get-local-name ((usocket usocket)) 
     
    353377    "java.nio.channels.DatagramChannel"))) 
    354378 
    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))) 
    357382         (selector (jdi:do-jstatic "java.nio.channels.Selector" "open")) 
    358383         (channels (mapcar #'socket sockets))) 
    359384    (unwind-protect 
    360385        (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))) 
    363387            (dolist (channel channels) 
    364388              (let ((chan (jdi:jop-deref channel))) 
     
    366390                                          "configureBlocking" 
    367391                                          "boolean") 
    368                             chan jfalse
     392                            chan (java:make-immediate-object nil :boolean)
    369393                (java:jcall (java:jmethod "java.nio.channels.SelectableChannel" 
    370394                                          "register" 
     
    380404                (let* ((selkeys (jdi:do-jmethod selector "selectedKeys")) 
    381405                       (selkey-iterator (jdi:do-jmethod selkeys "iterator")) 
    382                        ready-sockets
     406                       (%wait (wait-list-%wait wait-list))
    383407                  (loop while (java:jcall 
    384408                               (java:jmethod "java.util.Iterator" "hasNext") 
     
    389413                                  (chan (jdi:jop-deref 
    390414                                         (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 
    411418      (java:jcall (java:jmethod "java.nio.channels.Selector" "close") 
    412419                  (jdi:jop-deref selector)) 
    413420      ;; make all sockets blocking again. 
    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  
     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))) 
  • trunk/thirdparty/usocket/backend/clisp.lisp

    r3726 r3727  
    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 405 2008-07-30 19:26:46Z ehuelsmann
     2;;;; $URL: svn+ssh://common-lisp.net/project/usocket/svn/usocket/trunk/backend/clisp.lisp $ 
    33 
    44;;;; See LICENSE for licensing information. 
     
    5656               (signal usock-err :socket socket))))))) 
    5757 
    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) 
    5961  (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 
    6269  (let ((socket) 
    6370        (hostname (host-to-hostname host))) 
    6471    (with-mapped-conditions (socket) 
    65        (setf socket 
    66              (socket:socket-connect port hostname 
    67                                     :element-type element-type 
    68                                     :buffered t))) 
     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)))) 
    6981    (make-stream-socket :socket socket 
    7082                        :stream socket))) ;; the socket is a stream too 
     
    100112(defmethod socket-close ((usocket usocket)) 
    101113  "Close socket." 
     114  (when (wait-list usocket) 
     115     (remove-waiter (wait-list usocket) usocket)) 
    102116  (with-mapped-conditions (usocket) 
    103117    (close (socket usocket)))) 
    104118 
    105119(defmethod socket-close ((usocket stream-server-usocket)) 
     120  (when (wait-list usocket) 
     121     (remove-waiter (wait-list usocket) usocket)) 
    106122  (socket:socket-server-close (socket usocket))) 
    107123 
     
    131147 
    132148 
    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) 
    134160  (with-mapped-conditions () 
    135161    (multiple-value-bind 
    136162        (secs musecs) 
    137163        (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)) 
    143167             (status-list (if timeout 
    144168                              (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)))) 
    150177 
    151178 
     
    220247 
    221248  (defmethod socket-close ((usocket datagram-usocket)) 
     249    (when (wait-list usocket) 
     250       (remove-waiter (wait-list usocket) usocket)) 
    222251    (rawsock:sock-close (socket usocket))) 
    223252   
  • trunk/thirdparty/usocket/backend/cmucl.lisp

    r3726 r3727  
    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/trunk/backend/cmucl.lisp $ 
    33 
    44;;;; See LICENSE for licensing information. 
     
    5151                                               :condition condition)))) 
    5252 
    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) 
    5456  (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 
    5764  (let* ((socket)) 
    5865    (setf socket 
     
    101108(defmethod socket-close ((usocket stream-usocket)) 
    102109  "Close socket." 
     110  (when (wait-list usocket) 
     111     (remove-waiter (wait-list usocket) usocket)) 
    103112  (with-mapped-conditions (usocket) 
    104113    (close (socket-stream usocket)))) 
     
    106115(defmethod socket-close ((usocket usocket)) 
    107116  "Close socket." 
     117  (when (wait-list usocket) 
     118     (remove-waiter (wait-list usocket) usocket)) 
    108119  (with-mapped-conditions (usocket) 
    109120    (ext:close-socket (socket usocket)))) 
     
    166177  (unix:unix-gethostname)) 
    167178 
    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) 
    176190  (with-mapped-conditions () 
    177191    (alien:with-alien ((rfds (alien:struct unix:fd-set))) 
    178192       (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)) 
    181195       (multiple-value-bind 
    182196           (secs musecs) 
     
    184198         (multiple-value-bind 
    185199             (count err) 
    186              (unix:unix-fast-select (1+ (reduce #'max sockets 
    187                                                 :key #'socket)) 
     200             (unix:unix-fast-select (1+ (reduce #'max 
     201                                                (wait-list-%wait wait-list))) 
    188202                                    (alien:addr rfds) nil nil 
    189203                                    (when timeout secs) musecs) 
    190204           (if (<= 0 count) 
    191205               ;; 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))
    195209             (progn 
    196210               ;;###FIXME generate an error, except for EINTR 
  • trunk/thirdparty/usocket/backend/lispworks.lisp

    r3726 r3727  
    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/trunk/backend/lispworks.lisp $ 
    33 
    44;;;; See LICENSE for licensing information. 
     
    7474                    (raise-usock-err errno socket condition))))) 
    7575 
    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 
    8090  (let ((hostname (host-to-hostname host)) 
    8191        (stream)) 
     
    8393          (with-mapped-conditions () 
    8494             (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))) 
    86103    (if stream 
    87104        (make-stream-socket :socket (comm:socket-stream-socket stream) 
     
    94111                           (backlog 5) 
    95112                           (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 
    96118  (let* ((reuseaddress (if reuse-address-supplied-p reuse-address reuseaddress)) 
    97119         (comm::*use_so_reuseaddr* reuseaddress) 
     
    121143(defmethod socket-close ((usocket stream-usocket)) 
    122144  "Close socket." 
     145  (when (wait-list usocket) 
     146     (remove-waiter (wait-list usocket) usocket)) 
    123147  (close (socket-stream usocket))) 
    124148 
    125149(defmethod socket-close ((usocket usocket)) 
     150  (when (wait-list usocket) 
     151     (remove-waiter (wait-list usocket) usocket)) 
    126152  (with-mapped-conditions (usocket) 
    127153     (comm::close-socket (socket usocket)))) 
     
    161187(defun usocket-listen (usocket) 
    162188  (if (stream-usocket-p usocket) 
    163       (when (listen (socket usocket)) 
     189      (when (listen (socket-stream usocket)) 
    164190        usocket) 
    165191    (when (comm::socket-listen (socket usocket)) 
     
    173199 
    174200#-win32 
    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)))) 
     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))) 
    190231 
    191232 
     
    232273  (defconstant fionread 1074030207) 
    233274 
     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   
    234292  (fli:define-foreign-type ws-socket () '(:unsigned :int)) 
    235293  (fli:define-foreign-type win32-handle () '(:unsigned :int)) 
     
    276334  ;; Now that we have access to the system calls, this is the plan: 
    277335 
    278   ;; 1. Receive a list of sockets to listen to 
     336  ;; 1. Receive a wait-list with associated sockets to wait for 
    279337  ;; 2. Add all those sockets to an event handle 
    280338  ;; 3. Listen for an event on that handle (we have a LispWorks system:: internal for that) 
     
    296354          0)))) 
    297355 
    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  
    306356  (defun socket-ready-p (socket) 
    307357     (if (typep socket 'stream-usocket) 
     
    312362    (notany #'socket-ready-p sockets)) 
    313363 
    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  
     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   
    327371  (defun map-network-events (func network-events) 
    328372    (let ((event-map (fli:foreign-slot-value network-events 'network-events)) 
     
    330374      (unless (zerop event-map) 
    331375          (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? 
    333377              (funcall func (fli:foreign-aref error-array i))))))) 
    334378 
    335   (defun update-ready-slots (sockets) 
     379  (defun update-ready-and-state-slots (sockets) 
    336380     (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 
    339            (multiple-value-bind 
    340                  (rv network-events) 
    341                  (wsa-enum-network-events (os-socket-handle socket) 0 t) 
    342               (if (zerop rv) 
     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) 
    343389                 (map-network-events #'(lambda (err-code) 
    344390                                          (if (zerop err-code) 
    345                                              (setf (%ready-p socket) t) 
     391                                             (setf (%ready-p socket) t 
     392                                                   (state socket) :READ) 
    346393                                             (raise-usock-err err-code socket))) 
    347394                                     network-events) 
    348395                 (maybe-wsa-error rv socket)))))) 
    349396 
    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)) 
    352424   
    353425  );; end of WIN32-block 
  • trunk/thirdparty/usocket/backend/openmcl.lisp

    r3726 r3727  
    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 414 2008-08-07 18:50:26Z ehuelsmann
     2;;;; $URL: svn+ssh://common-lisp.net/project/usocket/svn/usocket/trunk/backend/openmcl.lisp $ 
    33 
    44;;;; See LICENSE for licensing information. 
     
    3333  (ccl::rletZ ((tv :timeval)) 
    3434    (ccl::ticks-to-timeval ticks-to-wait tv) 
     35    ;;### The trickery below can be moved to the wait-list now... 
    3536    (ccl::%stack-block ((infds ccl::*fd-set-size*)) 
    3637      (ccl::fd-zero infds) 
    3738      (let ((max-fd -1)) 
    3839        (dolist (sock sockets) 
    39           (let ((fd (openmcl-socket:socket-os-fd sock))) 
     40          (let ((fd (openmcl-socket:socket-os-fd (socket sock)))) 
    4041            (setf max-fd (max max-fd fd)) 
    4142            (ccl::fd-set fd infds))) 
     
    4445                              (if ticks-to-wait tv (ccl::%null-ptr))))) 
    4546          (when (> res 0) 
    46             (remove-if #'(lambda (x) 
    47                            (not (ccl::fd-is-set (openmcl-socket:socket-os-fd x) 
    48                                                 infds))) 
    49                        sockets))))))) 
     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))))) 
    5052 
    5153(defun raise-error-from-id (condition-id socket real-condition) 
     
    7375    :binary)) 
    7476 
    75 (defun socket-connect (host port &key (element-type 'character) timeout deadline nodelay) 
     77(defun socket-connect (host port &key (element-type 'character) timeout deadline nodelay 
     78                       local-host local-port) 
    7679  (with-mapped-conditions () 
    7780    (let ((mcl-sock 
    7881           (openmcl-socket:make-socket :remote-host (host-to-hostname host) 
    7982                                       :remote-port port 
     83                                       :local-host (when local-host (host-to-hostname local-host)) 
     84                                       :local-port local-port 
    8085                                       :format (to-format element-type) 
    8186                                       :deadline deadline 
     
    113118;; by the same object. 
    114119(defmethod socket-close ((usocket usocket))