sbcl stuff

This commit is contained in:
Ian Keane 2020-01-20 14:13:08 -05:00
parent 1d1dbc34df
commit 5d91dbb667
335 changed files with 119806 additions and 1 deletions

View file

@ -0,0 +1,152 @@
;;;; -*- Mode: Lisp -*-
;;;; Foreign functions defined by ECL's DFFI, used for #+ecl-bytecmp only.
;;;; See LICENSE for licensing information.
(in-package :usocket)
#+(and ecl-bytecmp windows)
(eval-when (:load-toplevel :execute)
(ffi:load-foreign-library "ws2_32.dll" :module "ws2_32"))
#+(and ecl-bytecmp windows)
(progn
(ffi:def-function ("gethostname" c-gethostname)
((name (* :unsigned-char))
(len :int))
:returning :int
:module "ws2_32")
(defun get-host-name ()
"Returns the hostname"
(ffi:with-foreign-object (name '(:array :unsigned-char 256))
(when (zerop (c-gethostname (ffi:char-array-to-pointer name) 256))
(ffi:convert-from-foreign-string name))))
(ffi:def-foreign-type ws-socket :unsigned-int)
(ffi:def-foreign-type ws-dword :unsigned-long)
(ffi:def-foreign-type ws-event :unsigned-int)
(ffi:def-struct wsa-network-events
(network-events :long)
(error-code (:array :int 10)))
(ffi:def-function ("WSACreateEvent" wsa-event-create)
()
:returning ws-event
:module "ws2_32")
(ffi:def-function ("WSACloseEvent" c-wsa-event-close)
((event-object ws-event))
:returning :int
:module "ws2_32")
(defun wsa-event-close (ws-event)
(not (zerop (c-wsa-event-close ws-event))))
(ffi:def-function ("WSAEnumNetworkEvents" wsa-enum-network-events)
((socket ws-socket)
(event-object ws-event)
(network-events (* wsa-network-events)))
:returning :int
:module "ws2_32")
(ffi:def-function ("WSAEventSelect" wsa-event-select)
((socket ws-socket)
(event-object ws-event)
(network-events :long))
:returning :int
:module "ws2_32")
(ffi:def-function ("WSAWaitForMultipleEvents" c-wsa-wait-for-multiple-events)
((number-of-events ws-dword)
(events (* ws-event))
(wait-all-p :int)
(timeout ws-dword)
(alertable-p :int))
:returning ws-dword
:module "ws2_32")
(defun wsa-wait-for-multiple-events (number-of-events events wait-all-p timeout alertable-p)
(c-wsa-wait-for-multiple-events number-of-events
events
(if wait-all-p -1 0)
timeout
(if alertable-p -1 0)))
(ffi:def-function ("ioctlsocket" wsa-ioctlsocket)
((socket ws-socket)
(cmd :long)
(argp (* :unsigned-long)))
:returning :int
:module "ws2_32")
(ffi:def-function ("WSAGetLastError" wsa-get-last-error)
()
:returning :int
:module "ws2_32")
(defun maybe-wsa-error (rv &optional socket)
(unless (zerop rv)
(raise-usock-err (wsa-get-last-error) socket)))
(defun bytes-available-for-read (socket)
(ffi:with-foreign-object (int-ptr :unsigned-long)
(maybe-wsa-error (wsa-ioctlsocket (socket-handle socket) fionread int-ptr)
socket)
(let ((int (ffi:deref-pointer int-ptr :unsigned-long)))
(prog1 int
(when (plusp int)
(setf (state socket) :read))))))
(defun map-network-events (func network-events)
(let ((event-map (ffi:get-slot-value network-events 'wsa-network-events 'network-events))
(error-array (ffi:get-slot-pointer network-events 'wsa-network-events 'error-code)))
(unless (zerop event-map)
(dotimes (i fd-max-events)
(unless (zerop (ldb (byte 1 i) event-map))
(funcall func (ffi:deref-array error-array '(:array :int 10) i)))))))
(defun update-ready-and-state-slots (sockets)
(dolist (socket sockets)
(if (%ready-p socket)
(progn
(setf (state socket) :READ))
(ffi:with-foreign-object (network-events 'wsa-network-events)
(let ((rv (wsa-enum-network-events (socket-handle socket) 0 network-events)))
(if (zerop rv)
(map-network-events
#'(lambda (err-code)
(if (zerop err-code)
(progn
(setf (state socket) :READ)
(when (stream-server-usocket-p socket)
(setf (%ready-p socket) t)))
(raise-usock-err err-code socket)))
network-events)
(maybe-wsa-error rv socket)))))))
(defun os-wait-list-%wait (wait-list)
(ffi:deref-pointer (wait-list-%wait wait-list) 'ws-event))
(defun (setf os-wait-list-%wait) (value wait-list)
(setf (ffi:deref-pointer (wait-list-%wait wait-list) 'ws-event) value))
(defun free-wait-list (wl)
(when (wait-list-p wl)
(unless (null (wait-list-%wait wl))
(wsa-event-close (os-wait-list-%wait wl))
(ffi:free-foreign-object (wait-list-%wait wl))
(setf (wait-list-%wait wl) nil))))
(defun %setup-wait-list (wait-list)
(setf (wait-list-%wait wait-list)
(ffi:allocate-foreign-object 'ws-event))
(setf (os-wait-list-%wait wait-list)
(wsa-event-create))
(ext:set-finalizer wait-list #'free-wait-list))
(defun os-socket-handle (usocket)
(socket-handle usocket))
) ; #+(and ecl-bytecmp windows)