Commit 74d127393ef78ff9f43ef778eca5e543482ef794

Thomas de Grivel 2017-05-21T16:57:20

Remove epoll- function prefix and implement more functions.

diff --git a/cffi-epoll.lisp b/cffi-epoll.lisp
index 1e37e79..4f8fba7 100644
--- a/cffi-epoll.lisp
+++ b/cffi-epoll.lisp
@@ -4,12 +4,18 @@
 (defcfun ("epoll_create" c-epoll-create) :int
   (size :int))
 
-(defun epoll-create (size)
+(defun create (&optional (size 10))
   (let ((fd (c-epoll-create size)))
     (when (< fd 0)
-      (error-errno "epoll-create"))
+      (error-errno "epoll_create"))
     fd))
 
+(defmacro with ((fdvar &optional (size 10)) &body body)
+  (let ((fd (gensym "FD-")))
+    `(let ((,fd (epoll-create ,size)))
+       (unwind-protect (let ((,fdvar ,fd)) ,@body)
+	 (unistd:close ,fd)))))
+
 (defcunion epoll-data
   (ptr :pointer)
   (fd :int)
@@ -26,21 +32,64 @@
   (fd :int)
   (event (:pointer (:struct epoll-event))))
 
-(defun epoll-ctl (epfd op fd events data)
+(defun ctl (epfd op fd events &key data-ptr data-fd data-u32 data-u64)
   (with-foreign-object (evt '(:struct epoll-event))
-    (setf (foreign-slot-value evt '(:struct epoll-event) 'events) events
-	  (foreign-slot-value evt '(:struct epoll-event) 'data) data)
+    (setf (foreign-slot-value evt '(:struct epoll-event) 'events) events)
+    (let ((data (foreign-slot-value evt '(:struct epoll-event) 'data)))
+      (with-foreign-slots ((ptr fd u32 u64) data (:union epoll-data))
+	(cond (data-ptr (setf ptr data-ptr))
+	      (data-fd  (setf fd  data-fd))
+	      (data-u32 (setf u32 data-u32))
+	      (data-u64 (setf u64 data-u64)))))
     (let ((r (c-epoll-ctl epfd op fd evt)))
       (when (< r 0)
 	(error-errno "epoll_ctl"))
       r)))
 
+(defun add (epfd fd events &key data-ptr data-fd data-u32 data-u64)
+  (ctl epfd +ctl-add+ fd events
+       :data-ptr data-ptr
+       :data-fd  data-fd
+       :data-u32 data-u32
+       :data-u64 data-u64))
+
+(defun mod (epfd fd events &key data-ptr data-fd data-u32 data-u64)
+  (ctl epfd +ctl-mod+ fd events
+       :data-ptr data-ptr
+       :data-fd  data-fd
+       :data-u32 data-u32
+       :data-u64 data-u64))
+
+(defun del (epfd fd events &key data-ptr data-fd data-u32 data-u64)
+  (ctl epfd +ctl-del+ fd events
+       :data-ptr data-ptr
+       :data-fd  data-fd
+       :data-u32 data-u32
+       :data-u64 data-u64))
+
 (defcfun ("epoll_wait" c-epoll-wait) :int
   (epfd :int)
   (events (:pointer (:struct epoll-event)))
   (maxevents :int)
   (timeout :int))
 
-(defun epoll-wait (epfd &optional (maxevents 64) (timeout -1))
-  (with-foreign-object (events '(:struct epoll-event) maxevents)
-    (c-epoll-wait )))
+(defmacro wait ((events-var fd-var epfd &optional
+			    (maxevents 1024)
+			    (timeout -1))
+		&body body)
+  (let ((events (gensym "EVENTS-"))
+	(e (gensym "E-"))
+	(e-data (gensym "E-DATA-"))
+	(i (gensym "I-"))
+	(m (gensym "M-")))
+    `(let ((,m ,maxevents))
+       (with-foreign-object (,events '(:struct epoll-event) ,m)
+	 (let ((,i (c-epoll-wait ,epfd ,events ,m ,timeout)))
+	   (when (< ,i 0)
+	     (error-errno "epoll_wait"))
+	   (dotimes (,i ,i)
+	     (let* ((,e (mem-aref ,events '(:struct epoll-event) ,i))
+		    (,events-var (foreign-slot-value ,e '(:struct epoll-event) 'events))
+		    (,e-data (foreign-slot-value ,e '(:struct epoll-event) 'data))
+		    (,fd-var (foreign-slot-value ,e-data '(:union epoll-data) 'fd)))
+	       ,@body)))))))