[cffi-devel] EPoll Interface

Volkan YAZICI yazicivo at ttmail.com
Fri Sep 11 08:49:57 UTC 2009


Hi,

I'm working on an epoll interface, but having trouble with nested
structs. Below code snippet is just a minor example where things
explode. Does anybody have an idea about what I might be missing?


Regards.

(defmacro prog1-let ((var val) &body body)
  `(let ((,var ,val))
     , at body
     ,var))

(defmacro maybe-error (test)
  (let ((errno (gensym)))
    `(when ,test
       (let ((,errno *errno*))
         (error (foreign-funcall "strerror" :int ,errno :string))))))

(defcvar "errno" :int)

; typedef union epoll_data {
; 	   void *ptr;
; 	   int fd;
; 	   __uint32_t u32;
; 	   __uint64_t u64;
; } epoll_data_t;

(defcstruct data
  (ptr :pointer)
  (fd  :int)
  (u32 :uint32)
  (u64 :uint64))

; struct epoll_event {
; 	   __uint32_t events;      /* Epoll events */
; 	   epoll_data_t data;      /* User data variable */
; };

(defcstruct event
  (events :uint32)
  (data   data))

; int epoll_ctl(int  epfd, int op, int  fd, struct epoll_event *event);

(defcfun "epoll_ctl" :int
  (epfd  :int)
  (op    :int)
  (fd    :int)
  (event (:pointer event)))

(defun control (epfd op fd events)
  (with-foreign-object (event-ptr 'event)
    ;; Set `EVENTS' slot of the `EVENTS'.
    (setf (foreign-slot-value event-ptr 'event 'events) events)
    ;; Empty `DATA' slot of the `EVENTS', and set `FD' slot of the `DATA'.
    (let ((data-ptr (foreign-slot-pointer event-ptr 'event 'data)))
      (setf (foreign-slot-value data-ptr 'data 'ptr) 0
            (foreign-slot-value data-ptr 'data 'u32) 0
            (foreign-slot-value data-ptr 'data 'u64) 0
            (foreign-slot-value data-ptr 'data 'fd)  fd))
    (prog1-let (res
                (foreign-funcall
                 "epoll_ctl"
                 :int epfd :int op :int fd :pointer event-ptr
                 :int))
      (maybe-error (minusp res)))))

; in: DEFUN CONTROL
;     (SETF (CFFI:FOREIGN-SLOT-VALUE EPOLL::DATA-PTR 'EPOLL::DATA 'EPOLL::PTR)
;             0
;           (CFFI:FOREIGN-SLOT-VALUE EPOLL::DATA-PTR 'EPOLL::DATA 'EPOLL::U32)
;             0
;           (CFFI:FOREIGN-SLOT-VALUE EPOLL::DATA-PTR 'EPOLL::DATA 'EPOLL::U64)
;             0
;           (CFFI:FOREIGN-SLOT-VALUE EPOLL::DATA-PTR 'EPOLL::DATA 'EPOLL::FD)
;             EPOLL::FD)
; --> PROGN SETF LET* MULTIPLE-VALUE-BIND LET PROGN CFFI::FOREIGN-SLOT-SET 
; --> SETF LET* MULTIPLE-VALUE-BIND LET PROGN CFFI::MEM-SET 
; --> CFFI-SYS:%MEM-SET LET SETF SB-KERNEL:%SET-SAP-REF-32 
; ==>
;   EPOLL::DATA-PTR
; 
; note: deleting unreachable code

;     (EPOLL::PROG1-LET
;      (EPOLL::RES
;       (CFFI:FOREIGN-FUNCALL "epoll_ctl" :INT EPOLL::EPFD :INT EPOLL::OP :INT
;                             EPOLL::FD :POINTER EPOLL::EVENT-PTR :INT))
;      (EPOLL::MAYBE-ERROR (< EPOLL::RES 0)))
; --> LET 
; ==>
;   EPOLL::RES
; 
; note: deleting unreachable code

;     (SETF (CFFI:FOREIGN-SLOT-VALUE EPOLL::DATA-PTR 'EPOLL::DATA 'EPOLL::PTR)
;             0
;           (CFFI:FOREIGN-SLOT-VALUE EPOLL::DATA-PTR 'EPOLL::DATA 'EPOLL::U32)
;             0
;           (CFFI:FOREIGN-SLOT-VALUE EPOLL::DATA-PTR 'EPOLL::DATA 'EPOLL::U64)
;             0
;           (CFFI:FOREIGN-SLOT-VALUE EPOLL::DATA-PTR 'EPOLL::DATA 'EPOLL::FD)
;             EPOLL::FD)
; --> PROGN SETF LET* MULTIPLE-VALUE-BIND LET PROGN CFFI::FOREIGN-SLOT-SET 
; --> SETF LET* MULTIPLE-VALUE-BIND LET PROGN CFFI::MEM-SET 
; --> CFFI-SYS:%MEM-SET LET SETF 
; ==>
;   (SB-KERNEL:%SET-SAP-REF-SAP EPOLL::DATA-PTR 0 #:VALUE174)
; 
; caught WARNING:
;   Asserted type SB-SYS:SYSTEM-AREA-POINTER conflicts with derived type
;   (VALUES (INTEGER 0 0) &OPTIONAL).
;   See also:
;     The SBCL Manual, Node "Handling of Types"
; 
; compilation unit finished
;   caught 1 WARNING condition
;   printed 2 notes




More information about the cffi-devel mailing list