Here's a corrected patch for 0005 that supersedes the one in my previous message.
Vladimir 2009/11/16 Vladimir Sedach <[email protected]>: > Hello, > > Here are some patches that make it easier to just use the multiplexer > object without having to go through the provided event loop/timer > machinery. This is done in three steps: make the monitor/harvest etc. > methods on multiplexer accept just file descriptors as well as > FD-ENTRYs (note that I've only done that for epoll in this set of > patches, others to come!), export the handler methods, and add an > optional flags parameter to the MONITOR-FD method (really useful for > epoll, the other backends I'm not sure about). > > Let me know what you think. I'd like to get these patches (or at least > the equivalent functionality of being able to use the multiplexer > without having to make FD-ENTRYs) into IOlib as I'm about to release > some software that uses it. > > Thanks, > Vladimir >
From 683a127a19bbca5d270fa96299d06c5fc58d3820 Mon Sep 17 00:00:00 2001 From: Vladimir Sedach <[email protected]> Date: Mon, 16 Nov 2009 02:52:42 -0500 Subject: [PATCH] Made epoll multiplexer take a simple integer file descriptor in addition to the FD-ENTRY structure. --- src/multiplex/backend-epoll.lisp | 99 +++++++++++++++++++------------------- 1 files changed, 50 insertions(+), 49 deletions(-) diff --git a/src/multiplex/backend-epoll.lisp b/src/multiplex/backend-epoll.lisp index 091e916..39c9cf5 100644 --- a/src/multiplex/backend-epoll.lisp +++ b/src/multiplex/backend-epoll.lisp @@ -21,64 +21,65 @@ &key (size +epoll-default-size-hint+)) (setf (slot-value mux 'fd) (isys:%sys-epoll-create size))) -(defun calc-epoll-flags (fd-entry) - (logior (if (fd-entry-read-handler fd-entry) - isys:epollin - 0) - (if (fd-entry-write-handler fd-entry) - isys:epollout - 0) - isys:epollpri)) - -(defmethod monitor-fd ((mux epoll-multiplexer) fd-entry) - (assert fd-entry (fd-entry) "Must supply an FD-ENTRY!") - (let ((flags (calc-epoll-flags fd-entry)) - (fd (fd-entry-fd fd-entry))) - (with-foreign-object (ev 'isys:epoll-event) - (isys:%sys-bzero ev isys:size-of-epoll-event) - (setf (foreign-slot-value ev 'isys:epoll-event 'isys:events) flags) - (setf (foreign-slot-value - (foreign-slot-value ev 'isys:epoll-event 'isys:data) - 'isys:epoll-data 'isys:fd) - fd) - (handler-case - (isys:%sys-epoll-ctl (fd-of mux) isys:epoll-ctl-add fd ev) - (isys:ebadf () - (warn "FD ~A is invalid, cannot monitor it." fd)) - (isys:eexist () - (warn "FD ~A is already monitored." fd)))))) - -(defmethod update-fd ((mux epoll-multiplexer) fd-entry event-type edge-change) - (declare (ignore event-type edge-change)) - (assert fd-entry (fd-entry) "Must supply an FD-ENTRY!") - (let ((flags (calc-epoll-flags fd-entry)) - (fd (fd-entry-fd fd-entry))) - (with-foreign-object (ev 'isys:epoll-event) - (isys:%sys-bzero ev isys:size-of-epoll-event) - (setf (foreign-slot-value ev 'isys:epoll-event 'isys:events) flags) - (setf (foreign-slot-value - (foreign-slot-value ev 'isys:epoll-event 'isys:data) - 'isys:epoll-data 'isys:fd) - fd) - (handler-case - (isys:%sys-epoll-ctl (fd-of mux) isys:epoll-ctl-mod fd ev) - (isys:ebadf () - (warn "FD ~A is invalid, cannot update its status." fd)) - (isys:enoent () - (warn "FD ~A was not monitored, cannot update its status." fd)))) - (values fd-entry))) - -(defmethod unmonitor-fd ((mux epoll-multiplexer) fd-entry) +(defun calc-epoll-flags (flags) + (logior (if (member :read flags) isys:epollin 0) + (if (member :write flags) isys:epollout 0) + (if (member :epoll-oneshot flags) isys:epolloneshot 0) + isys:epollpri)) ;; what to do about EPOLLPRI? + +(defmethod monitor-fd ((mux epoll-multiplexer) (fd-entry fd-entry) &optional flags) + (declare (ignore flags)) + (monitor-fd mux + (fd-entry-fd fd-entry) + (list (when (fd-entry-read-handler fd-entry) :read) + (when (fd-entry-write-handler fd-entry) :write)))) + +(defmacro with-epoll-event ((ev fd flags) &body body) + `(with-foreign-object (,ev 'isys:epoll-event) + (isys:%sys-bzero ,ev isys:size-of-epoll-event) + (setf (foreign-slot-value ,ev 'isys:epoll-event 'isys:events) + (calc-epoll-flags ,flags) + (foreign-slot-value + (foreign-slot-value ,ev 'isys:epoll-event 'isys:data) + 'isys:epoll-data 'isys:fd) + ,fd) + ,@body)) + +(defmethod monitor-fd ((mux epoll-multiplexer) (fd integer) &optional flags) + (with-epoll-event (ev fd flags) + (handler-case + (isys:%sys-epoll-ctl (fd-of mux) isys:epoll-ctl-add fd ev) + (isys:ebadf () + (warn "FD ~A is invalid, cannot monitor it." fd)) + (isys:eexist () + (warn "FD ~A is already monitored." fd))))) + +(defmethod update-fd ((mux epoll-multiplexer) (fd-entry fd-entry) flags edge-change) + (update-fd mux (fd-entry-fd fd-entry) flags edge-change)) + +(defmethod update-fd ((mux epoll-multiplexer) (fd integer) flags edge-change) + (declare (ignore edge-change)) + (with-epoll-event (ev fd flags) + (handler-case + (isys:%sys-epoll-ctl (fd-of mux) isys:epoll-ctl-mod fd ev) + (isys:ebadf () + (warn "FD ~A is invalid, cannot update its status." fd)) + (isys:enoent () + (warn "FD ~A was not monitored, cannot update its status." fd))))) + +(defmethod unmonitor-fd ((mux epoll-multiplexer) (fd-entry fd-entry)) + (unmonitor-fd mux (fd-entry-fd fd-entry))) + +(defmethod unmonitor-fd ((mux epoll-multiplexer) (fd integer)) (handler-case (isys:%sys-epoll-ctl (fd-of mux) isys:epoll-ctl-del - (fd-entry-fd fd-entry) + fd (null-pointer)) (isys:ebadf () - (warn "FD ~A is invalid, cannot unmonitor it." (fd-entry-fd fd-entry))) + (warn "FD ~A is invalid, cannot unmonitor it." fd)) (isys:enoent () - (warn "FD ~A was not monitored, cannot unmonitor it." - (fd-entry-fd fd-entry))))) + (warn "FD ~A was not monitored, cannot unmonitor it." fd)))) (defmethod harvest-events ((mux epoll-multiplexer) timeout) (with-foreign-object (events 'isys:epoll-event +epoll-max-events+) -- 1.6.3.3
_______________________________________________ IOLib-devel mailing list [email protected] http://common-lisp.net/cgi-bin/mailman/listinfo/iolib-devel
