├── .gitignore ├── lev-config.asd ├── config.lisp ├── src ├── lev.lisp ├── wrapper.lisp ├── exports.lisp └── bindings.lisp ├── LICENSE ├── lev.asd └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.fasl 2 | *.dx32fsl 3 | *.dx64fsl 4 | *.lx32fsl 5 | *.lx64fsl 6 | *.x86f 7 | *~ 8 | .#* -------------------------------------------------------------------------------- /lev-config.asd: -------------------------------------------------------------------------------- 1 | (cl:eval-when (:load-toplevel :execute) 2 | (asdf:operate 'asdf:load-op 'cffi-grovel)) 3 | 4 | (asdf:defsystem lev-config 5 | :author "Eitaro Fukamachi" 6 | :license "BSD 2-Clause" 7 | :version "0.1.0" 8 | :description "Configure libev to be used by lev." 9 | :serial t 10 | :components ((:file "config"))) 11 | -------------------------------------------------------------------------------- /config.lisp: -------------------------------------------------------------------------------- 1 | (in-package :cl-user) 2 | 3 | (defpackage :lev-config 4 | (:use :common-lisp) 5 | (:export #:load-from-custom-path 6 | #:libev)) 7 | 8 | (in-package :lev-config) 9 | 10 | (defmacro load-from-custom-path (path) 11 | "Define the path where libev is to be found: 12 | (ql:quickload :lev-config) 13 | (lev-config:load-from-custom-path \"/opt/local/lib/libev.so\") 14 | (ql:quickload :lev)" 15 | `(progn 16 | (cffi:define-foreign-library libev (t ,path)) 17 | (cffi:use-foreign-library libev))) 18 | -------------------------------------------------------------------------------- /src/lev.lisp: -------------------------------------------------------------------------------- 1 | (in-package :cl-user) 2 | (defpackage lev 3 | (:use :cl 4 | :lev.wrapper)) 5 | (in-package :lev) 6 | 7 | (eval-when (:compile-toplevel :load-toplevel :execute) 8 | (pushnew :lev-ev-compat3 *features*) 9 | (pushnew :lev-ev-full *features*)) 10 | 11 | (eval-when (:load-toplevel) 12 | (handler-case 13 | (cffi:foreign-library-loaded-p 'lev-config::libev) 14 | (error (m) 15 | (progn 16 | (cffi:define-foreign-library libev 17 | (:darwin (:or "libev.4.dylib" "libev.dylib")) 18 | (:unix (:or "libev.4.so" "libev.so.4" "libev.so")) 19 | (t (:default "libev"))) 20 | (unless (cffi:foreign-library-loaded-p 'libev) 21 | (cffi:use-foreign-library libev)))))) 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Eitaro Fukamachi 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /lev.asd: -------------------------------------------------------------------------------- 1 | #| 2 | This file is a part of lev project. 3 | Copyright (c) 2014 Eitaro Fukamachi (e.arrows@gmail.com) 4 | |# 5 | 6 | #| 7 | Author: Eitaro Fukamachi (e.arrows@gmail.com) 8 | |# 9 | 10 | (in-package :cl-user) 11 | (defpackage lev-asd 12 | (:use :cl :asdf)) 13 | (in-package :lev-asd) 14 | 15 | (defsystem lev 16 | :version "0.1.0" 17 | :author "Eitaro Fukamachi" 18 | :license "BSD 2-Clause" 19 | :depends-on (:cffi :lev-config) 20 | :components ((:module "src" 21 | :components 22 | ((:file "lev" :depends-on ("wrapper")) 23 | (:file "bindings" :depends-on ("lev")) 24 | (:file "exports" :depends-on ("bindings")) 25 | (:file "wrapper")))) 26 | :description "libev bindings for Common Lisp" 27 | :long-description 28 | #.(with-open-file (stream (merge-pathnames 29 | #p"README.md" 30 | (or *load-pathname* *compile-file-pathname*)) 31 | :if-does-not-exist nil 32 | :direction :input) 33 | (when stream 34 | (let ((seq (make-array (file-length stream) 35 | :element-type 'character 36 | :fill-pointer t))) 37 | (setf (fill-pointer seq) (read-sequence seq stream)) 38 | seq))) 39 | :in-order-to ((test-op (test-op lev-test)))) 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LEV 2 | 3 | LEV is [libev](http://software.schmorp.de/pkg/libev.html) bindings for Common Lisp. 4 | 5 | ## Usage 6 | 7 | ```common-lisp 8 | (ql:quickload :lev) 9 | 10 | (cffi:defcallback stdin-cb :void ((evloop :pointer) (io :pointer) (revents :int)) 11 | (declare (ignore revents)) 12 | (format t "stdin ready~%") 13 | (lev:ev-io-stop evloop io)) 14 | 15 | (cffi:defcallback timeout-cb :void ((evloop :pointer) (timer :pointer) (revents :int)) 16 | (declare (ignore timer revents)) 17 | (format t "timeout~%") 18 | (lev:ev-break evloop lev:+EVBREAK-ONE+)) 19 | 20 | (let ((evloop (lev:ev-default-loop 0)) 21 | (stdin-watcher (cffi:foreign-alloc '(:struct lev:ev-io))) 22 | (timeout-watcher (cffi:foreign-alloc '(:struct lev:ev-timer)))) 23 | (unwind-protect 24 | (progn 25 | ;; initialize an io watcher, then start it 26 | ;; this one will watch for stdin to become readable 27 | (lev:ev-io-init stdin-watcher 'stdin-cb 0 lev:+EV-READ+) 28 | (lev:ev-io-start evloop stdin-watcher) 29 | 30 | ;; initialize a timer watcher, then start it 31 | ;; simple non-repeating 5.5 second timeout 32 | (lev:ev-timer-init timeout-watcher 'timeout-cb 5.5d0 0d0) 33 | (lev:ev-timer-start evloop timeout-watcher) 34 | 35 | (format t "running~%") 36 | (lev:ev-run evloop 0)) 37 | (cffi:foreign-free stdin-watcher) 38 | (cffi:foreign-free timeout-watcher))) 39 | ``` 40 | 41 | ## Why not cl-ev? 42 | 43 | We already have [cl-ev](https://github.com/sbryant/cl-ev) for libev bindings, however I found there's some problems in it. 44 | 45 | * Wrapping with CLOS. It's bad for performance, obviously 46 | * Incomplete API 47 | * The author is inactive in Common Lisp world anymore 48 | 49 | ## See Also 50 | 51 | * [libev's documentation](http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod) 52 | 53 | ## Author 54 | 55 | * Eitaro Fukamachi (e.arrows@gmail.com) 56 | 57 | ## Copyright 58 | 59 | Copyright (c) 2014 Eitaro Fukamachi (e.arrows@gmail.com) 60 | 61 | ## License 62 | 63 | Licensed under the BSD 2-Clause License. 64 | -------------------------------------------------------------------------------- /src/wrapper.lisp: -------------------------------------------------------------------------------- 1 | (in-package :cl-user) 2 | (defpackage lev.wrapper 3 | (:use :cl) 4 | (:export :defanonenum 5 | :lispify 6 | :constant 7 | :enumvalue 8 | :variable)) 9 | (in-package :lev.wrapper) 10 | 11 | (cl:defmacro defanonenum (cl:&body enums) 12 | "Converts anonymous enums to defconstants." 13 | `(cl:progn ,@(cl:loop for value in enums 14 | for index = 0 then (cl:1+ index) 15 | when (cl:listp value) do (cl:setf index (cl:second value) 16 | value (cl:first value)) 17 | collect `(cl:defconstant ,value ,index)))) 18 | 19 | (cl:eval-when (:compile-toplevel :load-toplevel) 20 | (cl:unless (cl:fboundp 'lispify) 21 | (cl:defun lispify (name flag cl:&optional (package cl:*package*)) 22 | (cl:labels ((helper (lst last rest cl:&aux (c (cl:car lst))) 23 | (cl:cond 24 | ((cl:null lst) 25 | rest) 26 | ((cl:upper-case-p c) 27 | (helper (cl:cdr lst) 'upper 28 | (cl:case last 29 | ((lower digit) (cl:list* c #\- rest)) 30 | (cl:t (cl:cons c rest))))) 31 | ((cl:lower-case-p c) 32 | (helper (cl:cdr lst) 'lower (cl:cons (cl:char-upcase c) rest))) 33 | ((cl:digit-char-p c) 34 | (helper (cl:cdr lst) 'digit 35 | (cl:case last 36 | ((upper lower) (cl:list* c #\- rest)) 37 | (cl:t (cl:cons c rest))))) 38 | ((cl:char-equal c #\_) 39 | (helper (cl:cdr lst) '_ (cl:cons #\- rest))) 40 | (cl:t 41 | (cl:error "Invalid character: ~A" c))))) 42 | (cl:let ((fix (cl:case flag 43 | ((constant enumvalue) "+") 44 | (variable "*") 45 | (cl:t "")))) 46 | (cl:intern 47 | (cl:concatenate 48 | 'cl:string 49 | fix 50 | (cl:nreverse (helper (cl:concatenate 'cl:list name) cl:nil cl:nil)) 51 | fix) 52 | package)))))) 53 | -------------------------------------------------------------------------------- /src/exports.lisp: -------------------------------------------------------------------------------- 1 | (in-package :lev) 2 | 3 | (cl:export '#.(lispify "EV_MINPRI" 'constant)) 4 | (cl:export '#.(lispify "EV_MAXPRI" 'constant)) 5 | (cl:export '#.(lispify "EV_VERSION_MAJOR" 'constant)) 6 | (cl:export '#.(lispify "EV_VERSION_MINOR" 'constant)) 7 | 8 | (cl:export '#.(lispify "EV_UNDEF" 'enumvalue)) 9 | (cl:export '#.(lispify "EV_NONE" 'enumvalue)) 10 | (cl:export '#.(lispify "EV_READ" 'enumvalue)) 11 | (cl:export '#.(lispify "EV_WRITE" 'enumvalue)) 12 | (cl:export '#.(lispify "EV__IOFDSET" 'enumvalue)) 13 | (cl:export '#.(lispify "EV_IO" 'enumvalue)) 14 | (cl:export '#.(lispify "EV_TIMER" 'enumvalue)) 15 | #+lev-ev-compat3 16 | (cl:export '#.(lispify "EV_TIMEOUT" 'enumvalue)) 17 | (cl:export '#.(lispify "EV_PERIODIC" 'enumvalue)) 18 | (cl:export '#.(lispify "EV_SIGNAL" 'enumvalue)) 19 | (cl:export '#.(lispify "EV_CHILD" 'enumvalue)) 20 | (cl:export '#.(lispify "EV_STAT" 'enumvalue)) 21 | (cl:export '#.(lispify "EV_IDLE" 'enumvalue)) 22 | (cl:export '#.(lispify "EV_PREPARE" 'enumvalue)) 23 | (cl:export '#.(lispify "EV_CHECK" 'enumvalue)) 24 | (cl:export '#.(lispify "EV_EMBED" 'enumvalue)) 25 | (cl:export '#.(lispify "EV_FORK" 'enumvalue)) 26 | (cl:export '#.(lispify "EV_CLEANUP" 'enumvalue)) 27 | (cl:export '#.(lispify "EV_ASYNC" 'enumvalue)) 28 | (cl:export '#.(lispify "EV_CUSTOM" 'enumvalue)) 29 | (cl:export '#.(lispify "EV_ERROR" 'enumvalue)) 30 | 31 | (cl:export '#.(lispify "ev_watcher" 'classname)) 32 | 33 | (cl:export '#.(lispify "ev_watcher_list" 'classname)) 34 | 35 | (cl:export '#.(lispify "ev_watcher_time" 'classname)) 36 | 37 | (cl:export '#.(lispify "ev_io" 'classname)) 38 | 39 | (cl:export '#.(lispify "ev_timer" 'classname)) 40 | 41 | (cl:export '#.(lispify "ev_periodic" 'classname)) 42 | 43 | (cl:export '#.(lispify "ev_signal" 'classname)) 44 | 45 | (cl:export '#.(lispify "ev_child" 'classname)) 46 | 47 | #+lev-ev-stat 48 | (cl:export '#.(lispify "ev_stat" 'classname)) 49 | 50 | #+lev-ev-idle 51 | (cl:export '#.(lispify "ev_idle" 'classname)) 52 | 53 | (cl:export '#.(lispify "ev_prepare" 'classname)) 54 | 55 | (cl:export '#.(lispify "ev_check" 'classname)) 56 | 57 | #+lev-ev-fork 58 | (cl:export '#.(lispify "ev_fork" 'classname)) 59 | 60 | #+lev-ev-cleanup 61 | (cl:export '#.(lispify "ev_cleanup" 'classname)) 62 | 63 | #+lev-ev-embed 64 | (cl:export '#.(lispify "ev_embed" 'classname)) 65 | 66 | #+lev-ev-async 67 | (cl:export '#.(lispify "ev_async" 'classname)) 68 | 69 | (cl:export '#.(lispify "ev_any_watcher" 'classname)) 70 | (cl:export '#.(lispify "EVFLAG_AUTO" 'enumvalue)) 71 | (cl:export '#.(lispify "EVFLAG_NOENV" 'enumvalue)) 72 | (cl:export '#.(lispify "EVFLAG_FORKCHECK" 'enumvalue)) 73 | (cl:export '#.(lispify "EVFLAG_NOINOTIFY" 'enumvalue)) 74 | #+lev-ev-compat3 75 | (cl:export '#.(lispify "EVFLAG_NOSIGFD" 'enumvalue)) 76 | (cl:export '#.(lispify "EVFLAG_SIGNALFD" 'enumvalue)) 77 | (cl:export '#.(lispify "EVFLAG_NOSIGMASK" 'enumvalue)) 78 | 79 | (cl:export '#.(lispify "EVBACKEND_SELECT" 'enumvalue)) 80 | (cl:export '#.(lispify "EVBACKEND_POLL" 'enumvalue)) 81 | (cl:export '#.(lispify "EVBACKEND_EPOLL" 'enumvalue)) 82 | (cl:export '#.(lispify "EVBACKEND_KQUEUE" 'enumvalue)) 83 | (cl:export '#.(lispify "EVBACKEND_DEVPOLL" 'enumvalue)) 84 | (cl:export '#.(lispify "EVBACKEND_PORT" 'enumvalue)) 85 | (cl:export '#.(lispify "EVBACKEND_ALL" 'enumvalue)) 86 | (cl:export '#.(lispify "EVBACKEND_MASK" 'enumvalue)) 87 | 88 | (cl:export '#.(lispify "ev_version_major" 'function)) 89 | (cl:export '#.(lispify "ev_version_minor" 'function)) 90 | 91 | (cl:export '#.(lispify "ev_supported_backends" 'function)) 92 | (cl:export '#.(lispify "ev_recommended_backends" 'function)) 93 | (cl:export '#.(lispify "ev_embeddable_backends" 'function)) 94 | 95 | (cl:export '#.(lispify "ev_time" 'function)) 96 | 97 | (cl:export '#.(lispify "ev_sleep" 'function)) 98 | 99 | (cl:export '#.(lispify "ev_set_allocator" 'function)) 100 | 101 | (cl:export '#.(lispify "ev_set_syserr_cb" 'function)) 102 | 103 | (cl:export '#.(lispify "ev_default_loop" 'function)) 104 | 105 | (cl:export '#.(lispify "ev_default_loop_uc_" 'function)) 106 | 107 | (cl:export '#.(lispify "ev_is_default_loop" 'function)) 108 | 109 | (cl:export '#.(lispify "ev_loop_new" 'function)) 110 | 111 | (cl:export '#.(lispify "ev_now" 'function)) 112 | 113 | (cl:export '#.(lispify "ev_loop_destroy" 'function)) 114 | 115 | (cl:export '#.(lispify "ev_loop_fork" 'function)) 116 | 117 | (cl:export '#.(lispify "ev_backend" 'function)) 118 | 119 | (cl:export '#.(lispify "ev_now_update" 'function)) 120 | 121 | #+lev-ev-walk 122 | (cl:export '#.(lispify "ev_walk" 'function)) 123 | 124 | (cl:export '#.(lispify "EVRUN_NOWAIT" 'enumvalue)) 125 | (cl:export '#.(lispify "EVRUN_ONCE" 'enumvalue)) 126 | 127 | (cl:export '#.(lispify "EVBREAK_CANCEL" 'enumvalue)) 128 | (cl:export '#.(lispify "EVBREAK_ONE" 'enumvalue)) 129 | (cl:export '#.(lispify "EVBREAK_ALL" 'enumvalue)) 130 | 131 | (cl:export '#.(lispify "ev_run" 'function)) 132 | 133 | (cl:export '#.(lispify "ev_break" 'function)) 134 | 135 | (cl:export '#.(lispify "ev_ref" 'function)) 136 | (cl:export '#.(lispify "ev_unref" 'function)) 137 | 138 | (cl:export '#.(lispify "ev_once" 'function)) 139 | 140 | (cl:export '#.(lispify "ev_iteration" 'function)) 141 | (cl:export '#.(lispify "ev_depth" 'function)) 142 | (cl:export '#.(lispify "ev_verify" 'function)) 143 | 144 | (cl:export '#.(lispify "ev_set_io_collect_interval" 'function)) 145 | (cl:export '#.(lispify "ev_set_timeout_collect_interval" 'function)) 146 | 147 | (cl:export '#.(lispify "ev_set_userdata" 'function)) 148 | (cl:export '#.(lispify "ev_userdata" 'function)) 149 | (cl:export '#.(lispify "ev_set_invoke_pending_cb" 'function)) 150 | (cl:export '#.(lispify "ev_set_loop_release_cb" 'function)) 151 | 152 | (cl:export '#.(lispify "ev_pending_count" 'function)) 153 | (cl:export '#.(lispify "ev_invoke_pending" 'function)) 154 | 155 | (cl:export '#.(lispify "ev_suspend" 'function)) 156 | (cl:export '#.(lispify "ev_resume" 'function)) 157 | 158 | (cl:export 'ev-init) 159 | 160 | (cl:export 'ev-io-set) 161 | (cl:export 'ev-timer-set) 162 | (cl:export 'ev-periodic-set) 163 | (cl:export 'ev-signal-set) 164 | (cl:export 'ev-child-set) 165 | (cl:export 'ev-stat-set) 166 | (cl:export 'ev-idle-set) 167 | (cl:export 'ev-prepare-set) 168 | (cl:export 'ev-check-set) 169 | (cl:export 'ev-embed-set) 170 | (cl:export 'ev-fork-set) 171 | (cl:export 'ev-cleanup-set) 172 | (cl:export 'ev-async-set) 173 | 174 | (cl:export 'ev-io-init) 175 | (cl:export 'ev-timer-init) 176 | (cl:export 'ev-periodic-init) 177 | (cl:export 'ev-signal-init) 178 | (cl:export 'ev-child-init) 179 | (cl:export 'ev-stat-init) 180 | (cl:export 'ev-idle-init) 181 | (cl:export 'ev-prepare-init) 182 | (cl:export 'ev-check-init) 183 | (cl:export 'ev-embed-init) 184 | (cl:export 'ev-fork-init) 185 | (cl:export 'ev-cleanup-init) 186 | (cl:export 'ev-async-init) 187 | 188 | (cl:export 'ev-is-pending) 189 | (cl:export 'ev-is-active) 190 | 191 | (cl:export 'ev-cb) 192 | (cl:export 'ev-set-cb) 193 | (cl:export 'ev-priority) 194 | (cl:export 'ev-set-priority) 195 | (cl:export 'ev-periodic-at) 196 | 197 | (cl:export '#.(lispify "ev_feed_event" 'function)) 198 | (cl:export '#.(lispify "ev_feed_fd_event" 'function)) 199 | (cl:export '#.(lispify "ev_feed_signal" 'function)) 200 | (cl:export '#.(lispify "ev_feed_signal_event" 'function)) 201 | 202 | (cl:export '#.(lispify "ev_invoke" 'function)) 203 | (cl:export '#.(lispify "ev_clear_pending" 'function)) 204 | 205 | (cl:export '#.(lispify "ev_io_start" 'function)) 206 | (cl:export '#.(lispify "ev_io_stop" 'function)) 207 | 208 | (cl:export '#.(lispify "ev_timer_start" 'function)) 209 | (cl:export '#.(lispify "ev_timer_stop" 'function)) 210 | (cl:export '#.(lispify "ev_timer_again" 'function)) 211 | (cl:export '#.(lispify "ev_timer_remaining" 'function)) 212 | 213 | #+lev-ev-periodic 214 | (progn 215 | (cl:export '#.(lispify "ev_periodic_start" 'function)) 216 | (cl:export '#.(lispify "ev_periodic_stop" 'function)) 217 | (cl:export '#.(lispify "ev_periodic_again" 'function))) 218 | 219 | #+lev-ev-signal 220 | (progn 221 | (cl:export '#.(lispify "ev_signal_start" 'function)) 222 | (cl:export '#.(lispify "ev_signal_stop" 'function))) 223 | 224 | #+lev-ev-child 225 | (progn 226 | (cl:export '#.(lispify "ev_child_start" 'function)) 227 | (cl:export '#.(lispify "ev_child_stop" 'function))) 228 | 229 | #+lev-ev-stat 230 | (progn 231 | (cl:export '#.(lispify "ev_stat_start" 'function)) 232 | (cl:export '#.(lispify "ev_stat_stop" 'function)) 233 | (cl:export '#.(lispify "ev_stat_stat" 'function))) 234 | 235 | #+lev-ev-idle 236 | (progn 237 | (cl:export '#.(lispify "ev_idle_start" 'function)) 238 | (cl:export '#.(lispify "ev_idle_stop" 'function))) 239 | 240 | #+lev-ev-prepare 241 | (progn 242 | (cl:export '#.(lispify "ev_prepare_start" 'function)) 243 | (cl:export '#.(lispify "ev_prepare_stop" 'function))) 244 | 245 | #+lev-ev-check 246 | (progn 247 | (cl:export '#.(lispify "ev_check_start" 'function)) 248 | (cl:export '#.(lispify "ev_check_stop" 'function))) 249 | 250 | #+lev-ev-fork 251 | (progn 252 | (cl:export '#.(lispify "ev_fork_start" 'function)) 253 | (cl:export '#.(lispify "ev_fork_stop" 'function))) 254 | 255 | #+lev-ev-cleanup 256 | (progn 257 | (cl:export '#.(lispify "ev_cleanup_start" 'function)) 258 | (cl:export '#.(lispify "ev_cleanup_stop" 'function))) 259 | 260 | #+lev-ev-embed 261 | (progn 262 | (cl:export '#.(lispify "ev_embed_start" 'function)) 263 | (cl:export '#.(lispify "ev_embed_stop" 'function)) 264 | (cl:export '#.(lispify "ev_embed_sweep" 'function))) 265 | 266 | #+lev-ev-async 267 | (progn 268 | (cl:export '#.(lispify "ev_async_start" 'function)) 269 | (cl:export '#.(lispify "ev_async_stop" 'function)) 270 | (cl:export '#.(lispify "ev_async_send" 'function))) 271 | 272 | #+lev-ev-compat3 273 | (progn 274 | (cl:export '#.(lispify "EVLOOP_NONBLOCK" 'constant)) 275 | (cl:export '#.(lispify "EVLOOP_ONESHOT" 'constant)) 276 | (cl:export '#.(lispify "EVUNLOOP_CANCEL" 'constant)) 277 | (cl:export '#.(lispify "EVUNLOOP_ONE" 'constant)) 278 | (cl:export '#.(lispify "EVUNLOOP_ALL" 'constant))) 279 | 280 | (cl:export '#.(lispify "ev_loop" 'function)) 281 | (cl:export '#.(lispify "ev_unloop" 'function)) 282 | 283 | (cl:export '#.(lispify "ev_default_destroy" 'function)) 284 | 285 | (cl:export '#.(lispify "ev_default_fork" 'function)) 286 | 287 | (cl:export '#.(lispify "ev_loop_count" 'function)) 288 | 289 | (cl:export '#.(lispify "ev_loop_depth" 'function)) 290 | 291 | (cl:export '#.(lispify "ev_loop_verify" 'function)) 292 | -------------------------------------------------------------------------------- /src/bindings.lisp: -------------------------------------------------------------------------------- 1 | (in-package :lev) 2 | 3 | #+lev-ev-full 4 | (eval-when (:compile-toplevel :load-toplevel :execute) 5 | (pushnew :lev-ev-periodic *features*) 6 | (pushnew :lev-ev-stat *features*) 7 | (pushnew :lev-ev-prepare *features*) 8 | (pushnew :lev-ev-check *features*) 9 | (pushnew :lev-ev-idle *features*) 10 | (pushnew :lev-ev-fork *features*) 11 | (pushnew :lev-ev-cleanup *features*) 12 | #-windows 13 | (pushnew :lev-ev-child *features*) 14 | (pushnew :lev-ev-async *features*) 15 | (pushnew :lev-ev-embed *features*) 16 | (pushnew :lev-ev-signal *features*) 17 | #+lev-not-yet 18 | (pushnew :lev-ev-walk *features*)) 19 | 20 | (eval-when (:compile-toplevel :load-toplevel :execute) 21 | (defconstant #.(lispify "EV_MINPRI" 'constant) -2) 22 | (defconstant #.(lispify "EV_MAXPRI" 'constant) +2)) 23 | 24 | (defconstant #.(lispify "EV_VERSION_MAJOR" 'constant) 4) 25 | (defconstant #.(lispify "EV_VERSION_MINOR" 'constant) 15) 26 | 27 | (defanonenum 28 | (#.(lispify "EV_UNDEF" 'enumvalue) #xFFFFFFFF) ;; guaranteed to be invalid 29 | (#.(lispify "EV_NONE" 'enumvalue) #x00) ;; no events 30 | (#.(lispify "EV_READ" 'enumvalue) #x01) ;; ev_io detected read will not block 31 | (#.(lispify "EV_WRITE" 'enumvalue) #x02) ;; ev_io detected write will not block 32 | (#.(lispify "EV__IOFDSET" 'enumvalue) #x80) ;; internal use only 33 | (#.(lispify "EV_TIMER" 'enumvalue) #x00000100) ;; timer timed out 34 | (#.(lispify "EV_PERIODIC" 'enumvalue) #x00000200) ;; periodic timer timed out 35 | (#.(lispify "EV_SIGNAL" 'enumvalue) #x00000400) ;; signal was received 36 | (#.(lispify "EV_CHILD" 'enumvalue) #x00000800) ;; child/pid has status change 37 | (#.(lispify "EV_STAT" 'enumvalue) #x00001000) ;; stat data changed 38 | (#.(lispify "EV_IDLE" 'enumvalue) #x00002000) ;; event loop is idling 39 | (#.(lispify "EV_PREPARE" 'enumvalue) #x00004000) ;; event loop about to poll 40 | (#.(lispify "EV_CHECK" 'enumvalue) #x00008000) ;; event loop finished poll 41 | (#.(lispify "EV_EMBED" 'enumvalue) #x00010000) ;; embedded event loop needs sweep 42 | (#.(lispify "EV_FORK" 'enumvalue) #x00020000) ;; event loop resumed in child 43 | (#.(lispify "EV_CLEANUP" 'enumvalue) #x00040000) ;; event loop resumed in child 44 | (#.(lispify "EV_ASYNC" 'enumvalue) #x00080000) ;; async intra-loop signal 45 | (#.(lispify "EV_CUSTOM" 'enumvalue) #x01000000) ;; for use by user code 46 | (#.(lispify "EV_ERROR" 'enumvalue) #x80000000)) ;; sent when an error occurs 47 | 48 | ;; alias for type-detection 49 | (defconstant #.(lispify "EV_IO" 'enumvalue) #.(lispify "EV_READ" 'enumvalue)) 50 | 51 | #+lev-ev-compat3 52 | ;; pre 4.0 API compatibility 53 | (defconstant #.(lispify "EV_TIMEOUT" 'enumvalue) #.(lispify "EV_TIMER" 'enumvalue)) 54 | 55 | (eval-when (:compile-toplevel :load-toplevel) 56 | ;; shared by all watchers 57 | (defparameter *ev-watcher-slots* 58 | '((#.(lispify "active" 'slotname) :int) ;; private 59 | (#.(lispify "pending" 'slotname) :int) ;; private 60 | (#.(lispify "priority" 'slotname) :int) ;; private 61 | (#.(lispify "data" 'slotname) :pointer) ;; rw 62 | (#.(lispify "cb" 'slotname) :pointer))) 63 | (defparameter *ev-watcher-list-slots* 64 | `(,@*ev-watcher-slots* 65 | ;; private 66 | (#.(lispify "next" 'slotname) :pointer))) 67 | (defparameter *ev-watcher-time-slots* 68 | `(,@*ev-watcher-slots* 69 | ;; private 70 | (#.(lispify "at" 'slotname) :double)))) 71 | 72 | #.`(cffi:defcstruct #.(lispify "ev_watcher" 'classname) 73 | ,@*ev-watcher-slots*) 74 | 75 | #.`(cffi:defcstruct #.(lispify "ev_watcher_list" 'classname) 76 | ,@*ev-watcher-list-slots*) 77 | 78 | #.`(cffi:defcstruct #.(lispify "ev_watcher_time" 'classname) 79 | ,@*ev-watcher-time-slots*) 80 | 81 | ;; invoked when fd is either EV_READable or EV_WRITEable 82 | ;; revent EV_READ, EV_WRITE 83 | #.`(cffi:defcstruct #.(lispify "ev_io" 'classname) 84 | ,@*ev-watcher-list-slots* 85 | (#.(lispify "fd" 'slotname) :int) ;; ro 86 | (#.(lispify "events" 'slotname) :int)) ;; ro 87 | 88 | ;; invoked after a specific time, repeatable (based on monotonic clock) 89 | ;; revent EV_TIMEOUT 90 | #.`(cffi:defcstruct #.(lispify "ev_timer" 'classname) 91 | ,@*ev-watcher-time-slots* 92 | (#.(lispify "repeat" 'slotname) :double)) ;; rw 93 | 94 | ;; invoked at some specific time, possibly repeating at regular intervals (based on UTC) 95 | ;; revent EV_PERIODIC 96 | #.`(cffi:defcstruct #.(lispify "ev_periodic" 'classname) 97 | ,@*ev-watcher-time-slots* 98 | (#.(lispify "offset" 'slotname) :double) ;; rw 99 | (#.(lispify "interval" 'slotname) :double) ;; rw 100 | (#.(lispify "reschedule_cb" 'slotname) :pointer)) ;; rw 101 | 102 | ;; invoked when the given signal has been received 103 | ;; revent EV_SIGNAL 104 | #.`(cffi:defcstruct #.(lispify "ev_signal" 'classname) 105 | ,@*ev-watcher-list-slots* 106 | (#.(lispify "signum" 'slotname) :int)) ;; ro 107 | 108 | ;; invoked when sigchld is received and waitpid indicates the given pid 109 | ;; revent EV_CHILD 110 | #.`(cffi:defcstruct #.(lispify "ev_child" 'classname) 111 | ,@*ev-watcher-list-slots* 112 | (#.(lispify "flags" 'slotname) :int) ;; private 113 | (#.(lispify "pid" 'slotname) :int) ;; ro 114 | (#.(lispify "rpid" 'slotname) :int) ;; rw, holds the received pid 115 | (#.(lispify "rstatus" 'slotname) :int)) ;; rw, holds the exit status, use the macros from sys/wait.h 116 | 117 | ;; invoked each time the stat data changes for a given path 118 | ;; revent EV_STAT 119 | #+lev-ev-stat 120 | #.`(cffi:defcstruct #.(lispify "ev_stat" 'classname) 121 | ,@*ev-watcher-list-slots* 122 | (#.(lispify "timer" 'slotname) (:struct #.(lispify "ev_timer" 'classname))) ;; private 123 | (#.(lispify "interval" 'slotname) :double) ;; ro 124 | (#.(lispify "path" 'slotname) :string) ;; ro 125 | (#.(lispify "prev" 'slotname) :pointer) ;; ro 126 | (#.(lispify "attr" 'slotname) :pointer) ;; ro 127 | 128 | ;; wd for inotify, fd for kqueue 129 | (#.(lispify "wd" 'slotname) :int)) 130 | 131 | ;; invoked when the nothing else needs to be done, keeps the process from blocking 132 | ;; revent EV_IDLE 133 | #+lev-ev-idle 134 | #.`(cffi:defcstruct #.(lispify "ev_idle" 'classname) 135 | ,@*ev-watcher-slots*) 136 | 137 | ;; invoked for each run of the mainloop, just before the blocking call 138 | ;; you can still change events in any way you like 139 | ;; revent EV_PREPARE 140 | #.`(cffi:defcstruct #.(lispify "ev_prepare" 'classname) 141 | ,@*ev-watcher-slots*) 142 | 143 | ;; invoked for each run of the mainloop, just after the blocking call 144 | ;; revent EV_CHECK 145 | #.`(cffi:defcstruct #.(lispify "ev_check" 'classname) 146 | ,@*ev-watcher-slots*) 147 | 148 | #+lev-ev-fork 149 | ;; the callback gets invoked before check in the child process when a fork was detected 150 | ;; revent EV_FORK 151 | #.`(cffi:defcstruct #.(lispify "ev_fork" 'classname) 152 | ,@*ev-watcher-slots*) 153 | 154 | #+lev-ev-cleanup 155 | ;; is invoked just before the loop gets destroyed 156 | ;; revent EV_CLEANUP 157 | #.`(cffi:defcstruct #.(lispify "ev_cleanup" 'classname) 158 | ,@*ev-watcher-slots*) 159 | 160 | #+lev-ev-embed 161 | ;; used to embed an event loop inside another 162 | ;; the callback gets invoked when the event loop has handled events, and can be 0 163 | #.`(cffi:defcstruct #.(lispify "ev_embed" 'classname) 164 | ,@*ev-watcher-slots* 165 | 166 | (#.(lispify "other" 'slotname) :pointer) ;; ro 167 | (#.(lispify "io" 'slotname) (:struct #.(lispify "ev_io" 'classname))) ;; private 168 | (#.(lispify "prepare" 'slotname) (:struct #.(lispify "ev_prepare" 'classname))) ;; private 169 | (#.(lispify "check" 'slotname) (:struct #.(lispify "ev_check" 'classname))) ;; unused 170 | (#.(lispify "timer" 'slotname) (:struct #.(lispify "ev_timer" 'classname))) ;; unused 171 | (#.(lispify "periodic" 'slotname) (:struct #.(lispify "ev_periodic" 'classname))) ;; unused 172 | (#.(lispify "idle" 'slotname) (:struct #.(lispify "ev_idle" 'classname))) ;; unused 173 | (#.(lispify "fork" 'slotname) (:struct #.(lispify "ev_fork" 'classname))) ;; private 174 | #+lev-ev-cleanup 175 | (#.(lispify "cleanup" 'slotname) (:struct #.(lispify "ev_cleanup" 'classname)))) ;; unused 176 | 177 | #+lev-ev-async 178 | ;; invoked when somebody calls ev_async_send on the watcher 179 | ;; revent EV_ASYNC 180 | #.`(cffi:defcstruct #.(lispify "ev_async" 'classname) 181 | ,@*ev-watcher-slots* 182 | (#.(lispify "sent" 'slotname) :pointer)) ;; private 183 | 184 | ;; the presence of this union forces similar struct layout 185 | #.`(cffi:defcunion #.(lispify "ev_any_watcher" 'classname) 186 | (#.(lispify "w" 'slotname) (:struct #.(lispify "ev_watcher" 'classname))) 187 | (#.(lispify "wl" 'slotname) (:struct #.(lispify "ev_watcher_list" 'classname))) 188 | (#.(lispify "io" 'slotname) (:struct #.(lispify "ev_io" 'classname))) 189 | (#.(lispify "timer" 'slotname) (:struct #.(lispify "ev_timer" 'classname))) 190 | (#.(lispify "periodic" 'slotname) (:struct #.(lispify "ev_periodic" 'classname))) 191 | (#.(lispify "signal" 'slotname) (:struct #.(lispify "ev_signal" 'classname))) 192 | (#.(lispify "child" 'slotname) (:struct #.(lispify "ev_child" 'classname))) 193 | #+lev-ev-stat 194 | (#.(lispify "stat" 'slotname) (:struct #.(lispify "ev_stat" 'classname))) 195 | #+lev-ev-idle 196 | (#.(lispify "idle" 'slotname) (:struct #.(lispify "ev_idle" 'classname))) 197 | (#.(lispify "prepare" 'slotname) (:struct #.(lispify "ev_prepare" 'classname))) 198 | (#.(lispify "check" 'slotname) (:struct #.(lispify "ev_check" 'classname))) 199 | #+lev-ev-fork 200 | (#.(lispify "fork" 'slotname) (:struct #.(lispify "ev_fork" 'classname))) 201 | #+lev-ev-cleanup 202 | (#.(lispify "cleanup" 'slotname) (:struct #.(lispify "ev_cleanup" 'classname))) 203 | #+lev-ev-embed 204 | (#.(lispify "embed" 'slotname) (:struct #.(lispify "ev_embed" 'classname))) 205 | #+lev-ev-async 206 | (#.(lispify "async" 'slotname) (:struct #.(lispify "ev_async" 'classname)))) 207 | 208 | ;; flag bits for ev_default_loop and ev_loop_new 209 | (defanonenum 210 | ;; the default 211 | (#.(lispify "EVFLAG_AUTO" 'enumvalue) #x00000000) ;; not quite a mask 212 | ;; flag bits 213 | (#.(lispify "EVFLAG_NOENV" 'enumvalue) #x01000000) ;; do NOT consult environment 214 | (#.(lispify "EVFLAG_FORKCHECK" 'enumvalue) #x02000000) ;; check for a fork in each iteration 215 | ;; debugging/feature disable 216 | (#.(lispify "EVFLAG_NOINOTIFY" 'enumvalue) #x00100000) ;; do not attempt to use inotify 217 | #+lev-ev-compat3 218 | (#.(lispify "EVFLAG_NOSIGFD" 'enumvalue) 0) ;; compatibility to pre-3.9 219 | (#.(lispify "EVFLAG_SIGNALFD" 'enumvalue) #x00200000) ;; attempt to use signalfd 220 | (#.(lispify "EVFLAG_NOSIGMASK" 'enumvalue) #x00400000)) ;; avoid modifying the signal mask 221 | 222 | ;; method bits to be ored together 223 | (defanonenum 224 | (#.(lispify "EVBACKEND_SELECT" 'enumvalue) #x00000001) ;; about anywhere 225 | (#.(lispify "EVBACKEND_POLL" 'enumvalue) #x00000002) ;; !win 226 | (#.(lispify "EVBACKEND_EPOLL" 'enumvalue) #x00000004) ;; linux 227 | (#.(lispify "EVBACKEND_KQUEUE" 'enumvalue) #x00000008) ;; bsd 228 | (#.(lispify "EVBACKEND_DEVPOLL" 'enumvalue) #x00000010) ;; solaris 8, NYI 229 | (#.(lispify "EVBACKEND_PORT" 'enumvalue) #x00000020) ;; solaris 10 230 | (#.(lispify "EVBACKEND_ALL" 'enumvalue) #x0000003F) ;; all known backends 231 | (#.(lispify "EVBACKEND_MASK" 'enumvalue) #x0000FFFF)) ;; all future backends 232 | 233 | (cffi:defcfun ("ev_version_major" #.(lispify "ev_version_major" 'function)) :int) 234 | (cffi:defcfun ("ev_version_minor" #.(lispify "ev_version_minor" 'function)) :int) 235 | 236 | (cffi:defcfun ("ev_supported_backends" #.(lispify "ev_supported_backends" 'function)) :unsigned-int) 237 | (cffi:defcfun ("ev_recommended_backends" #.(lispify "ev_recommended_backends" 'function)) :unsigned-int) 238 | (cffi:defcfun ("ev_embeddable_backends" #.(lispify "ev_embeddable_backends" 'function)) :unsigned-int) 239 | 240 | (cffi:defcfun ("ev_time" #.(lispify "ev_time" 'function)) :double) 241 | ;; sleep for a while 242 | (cffi:defcfun ("ev_sleep" #.(lispify "ev_sleep" 'function)) :void 243 | (delay :double)) 244 | 245 | ;; Sets the allocation function to use, works like realloc. 246 | ;; It is used to allocate and free memory. 247 | ;; If it returns zero when memory needs to be allocated, the library might abort 248 | ;; or take some potentially destructive action. 249 | ;; The default is your system realloc function. 250 | (cffi:defcfun ("ev_set_allocator" #.(lispify "ev_set_allocator" 'function)) :void 251 | (cb :pointer)) 252 | 253 | ;; set the callback function to call on a 254 | ;; retryable syscall error 255 | ;; (such as failed select, poll, epoll_wait) 256 | (cffi:defcfun ("ev_set_syserr_cb" #.(lispify "ev_set_syserr_cb" 'function)) :void 257 | (cb :pointer)) 258 | 259 | ;; the default loop is the only one that handles signals and child watchers 260 | ;; you can call this as often as you like 261 | (cffi:defcfun ("ev_default_loop" #.(lispify "ev_default_loop" 'function)) :pointer 262 | (flags :unsigned-int)) 263 | 264 | (cffi:defcfun ("ev_default_loop_uc_" #.(lispify "ev_default_loop_uc_" 'function)) :pointer) 265 | 266 | (cffi:defcfun ("ev_is_default_loop" #.(lispify "ev_is_default_loop" 'function)) :int 267 | (loop :pointer)) 268 | 269 | ;; create and destroy alternative loops that don't handle signals 270 | (cffi:defcfun ("ev_loop_new" #.(lispify "ev_loop_new" 'function)) :pointer 271 | (flags :unsigned-int)) 272 | 273 | (cffi:defcfun ("ev_now" #.(lispify "ev_now" 'function)) :double 274 | (loop :pointer)) 275 | 276 | ;; destroy event loops, also works for the default loop 277 | (cffi:defcfun ("ev_loop_destroy" #.(lispify "ev_loop_destroy" 'function)) :void 278 | (loop :pointer)) 279 | 280 | ;; this needs to be called after fork, to duplicate the loop 281 | ;; when you want to re-use it in the child 282 | ;; you can call it in either the parent or the child 283 | ;; you can actually call it at any time, anywhere :) 284 | (cffi:defcfun ("ev_loop_fork" #.(lispify "ev_loop_fork" 'function)) :void 285 | (loop :pointer)) 286 | 287 | ;; backend in use by loop 288 | (cffi:defcfun ("ev_backend" #.(lispify "ev_backend" 'function)) :unsigned-int 289 | (loop :pointer)) 290 | 291 | ;; update event loop time 292 | (cffi:defcfun ("ev_now_update" #.(lispify "ev_now_update" 'function)) :void 293 | (loop :pointer)) 294 | 295 | #+lev-ev-walk 296 | ;; walk (almost) all watchers in the loop of a given type, invoking the 297 | ;; callback on every such watcher. The callback might stop the watcher, 298 | ;; but do nothing else with the loop 299 | (cffi:defcfun ("ev_walk" #.(lispify "ev_walk" 'function)) :void 300 | (types :int) 301 | (cb :pointer)) 302 | 303 | ;; ev_run flags values 304 | (defanonenum 305 | (#.(lispify "EVRUN_NOWAIT" 'enumvalue) 1) ;; do not block/wait 306 | (#.(lispify "EVRUN_ONCE" 'enumvalue) 2)) ;; block *once* only 307 | 308 | ;; ev_break how values 309 | (defanonenum 310 | (#.(lispify "EVBREAK_CANCEL" 'enumvalue) 0) ;; undo unloop 311 | (#.(lispify "EVBREAK_ONE" 'enumvalue) 1) ;; unloop once 312 | (#.(lispify "EVBREAK_ALL" 'enumvalue) 2)) ;; unloop all loops 313 | 314 | (cffi:defcfun ("ev_run" #.(lispify "ev_run" 'function)) :int 315 | (loop :pointer) 316 | (flags :int)) 317 | 318 | ;; break out of the loop 319 | (cffi:defcfun ("ev_break" #.(lispify "ev_break" 'function)) :void 320 | (loop :pointer) 321 | (how :int)) 322 | 323 | ;; ref/unref can be used to add or remove a refcount on the mainloop. every watcher 324 | ;; keeps one reference. if you have a long-running watcher you never unregister that 325 | ;; should not keep ev_loop from running, unref() after starting, and ref() before stopping. 326 | (cffi:defcfun ("ev_ref" #.(lispify "ev_ref" 'function)) :void 327 | (loop :pointer)) 328 | (cffi:defcfun ("ev_unref" #.(lispify "ev_unref" 'function)) :void 329 | (loop :pointer)) 330 | 331 | ;; convenience function, wait for a single event, without registering an event watcher 332 | ;; if timeout is < 0, do wait indefinitely 333 | (cffi:defcfun ("ev_once" #.(lispify "ev_once" 'function)) :void 334 | (loop :pointer) 335 | (fd :int) 336 | (events :int) 337 | (timeout :double) 338 | (cb :pointer) 339 | (arg :pointer)) 340 | 341 | ;; number of loop iterations 342 | (cffi:defcfun ("ev_iteration" #.(lispify "ev_iteration" 'function)) :unsigned-int 343 | (loop :pointer)) 344 | ;; #ev_loop enters - #ev_loop leaves 345 | (cffi:defcfun ("ev_depth" #.(lispify "ev_depth" 'function)) :unsigned-int 346 | (loop :pointer)) 347 | ;; about if loop data corrupted 348 | (cffi:defcfun ("ev_verify" #.(lispify "ev_verify" 'function)) :void 349 | (loop :pointer)) 350 | 351 | ;; sleep at least this time, default 0 352 | (cffi:defcfun ("ev_set_io_collect_interval" #.(lispify "ev_set_io_collect_interval" 'function)) :void 353 | (loop :pointer) 354 | (interval :double)) 355 | ;; sleep at least this time, default 0 356 | (cffi:defcfun ("ev_set_timeout_collect_interval" #.(lispify "ev_set_timeout_collect_interval" 'function)) :void 357 | (loop :pointer) 358 | (interval :double)) 359 | 360 | ;; advanced stuff for threading etc. support, see docs 361 | (cffi:defcfun ("ev_set_userdata" #.(lispify "ev_set_userdata" 'function)) :void 362 | (loop :pointer) 363 | (data :pointer)) 364 | (cffi:defcfun ("ev_userdata" #.(lispify "ev_userdata" 'function)) :pointer 365 | (loop :pointer)) 366 | (cffi:defcfun ("ev_set_invoke_pending_cb" #.(lispify "ev_set_invoke_pending_cb" 'function)) :void 367 | (loop :pointer) 368 | (invoke_pending_cb :pointer)) 369 | (cffi:defcfun ("ev_set_loop_release_cb" #.(lispify "ev_set_loop_release_cb" 'function)) :void 370 | (loop :pointer) 371 | (release :pointer) 372 | (acquire :pointer)) 373 | 374 | ;; number of pending events, if any 375 | (cffi:defcfun ("ev_pending_count" #.(lispify "ev_pending_count" 'function)) :unsigned-int 376 | (loop :pointer)) 377 | ;; invoke all pending watchers 378 | (cffi:defcfun ("ev_invoke_pending" #.(lispify "ev_invoke_pending" 'function)) :void 379 | (loop :pointer)) 380 | 381 | ;; stop/start the timer handling. 382 | (cffi:defcfun ("ev_suspend" #.(lispify "ev_suspend" 'function)) :void 383 | (loop :pointer)) 384 | (cffi:defcfun ("ev_resume" #.(lispify "ev_resume" 'function)) :void 385 | (loop :pointer)) 386 | 387 | (defun ev-init (ev cb_) 388 | (cffi:with-foreign-slots ((active pending priority cb) ev (:struct ev-io)) 389 | (setf active 0 390 | pending 0 391 | priority 0 392 | cb (cffi:get-callback cb_)))) 393 | 394 | (defun ev-io-set (ev fd_ events_) 395 | (cffi:with-foreign-slots ((fd events) ev (:struct ev-io)) 396 | (setf fd fd_ 397 | events (logxor events_ +ev--iofdset+)))) 398 | 399 | (defun ev-timer-set (ev after_ repeat_) 400 | (cffi:with-foreign-slots ((at repeat) ev (:struct ev-timer)) 401 | (setf at after_ 402 | repeat repeat_))) 403 | 404 | (defun ev-periodic-set (ev offset_ interval_ reschedule-cb_) 405 | (cffi:with-foreign-slots ((offset interval reschedule-cb) ev (:struct ev-periodic)) 406 | (setf offset offset_ 407 | interval interval_ 408 | reschedule-cb reschedule-cb_))) 409 | 410 | (defun ev-signal-set (ev signum) 411 | (setf (cffi:foreign-slot-value ev '(:struct ev-signal) 'signum) signum)) 412 | 413 | (defun ev-child-set (ev pid_ trace_) 414 | (cffi:with-foreign-slots ((pid flags) ev (:struct ev-child)) 415 | (setf pid pid_ 416 | flags (if trace_ 1 0)))) 417 | 418 | (defun ev-stat-set (ev path_ interval_) 419 | (cffi:with-foreign-slots ((path interval wd) ev (:struct ev-stat)) 420 | (setf path path_ 421 | interval interval_ 422 | wd -2))) 423 | 424 | ;; nop, yes, this is a serious in-joke 425 | (defun ev-idle-set (ev) (declare (ignore ev))) 426 | ;; nop, yes, this is a serious in-joke 427 | (defun ev-prepare-set (ev) (declare (ignore ev))) 428 | ;; nop, yes, this is a serious in-joke 429 | (defun ev-check-set (ev) (declare (ignore ev))) 430 | 431 | (defun ev-embed-set (ev other_) 432 | (setf (cffi:foreign-slot-value ev '(:struct ev-embed) 'other) other_)) 433 | 434 | ;; nop, yes, this is a serious in-joke 435 | (defun ev-fork-set (ev) (declare (ignore ev))) 436 | ;; nop, yes, this is a serious in-joke 437 | (defun ev-cleanup-set (ev) (declare (ignore ev))) 438 | ;; nop, yes, this is a serious in-joke 439 | (defun ev-async-set (ev) (declare (ignore ev))) 440 | 441 | (defun ev-io-init (ev cb fd events) 442 | (ev-init ev cb) 443 | (ev-io-set ev fd events)) 444 | 445 | (defun ev-timer-init (ev cb after repeat) 446 | (ev-init ev cb) 447 | (ev-timer-set ev after repeat)) 448 | 449 | (defun ev-periodic-init (ev cb offset interval reschedule-cb) 450 | (ev-init ev cb) 451 | (ev-periodic-set ev offset interval reschedule-cb)) 452 | 453 | (defun ev-signal-init (ev cb signum) 454 | (ev-init ev cb) 455 | (ev-signal-set ev signum)) 456 | 457 | (defun ev-child-init (ev cb pid trace) 458 | (ev-init ev cb) 459 | (ev-child-set ev pid trace)) 460 | 461 | (defun ev-stat-init (ev cb path interval) 462 | (ev-init ev cb) 463 | (ev-stat-set ev path interval)) 464 | 465 | (defun ev-idle-init (ev cb) 466 | (ev-init ev cb) 467 | (ev-idle-set ev)) 468 | 469 | (defun ev-prepare-init (ev cb) 470 | (ev-init ev cb) 471 | (ev-prepare-set ev)) 472 | 473 | (defun ev-check-init (ev cb) 474 | (ev-init ev cb) 475 | (ev-check-set ev)) 476 | 477 | (defun ev-embed-init (ev cb other) 478 | (ev-init ev cb) 479 | (ev-embed-set ev other)) 480 | 481 | (defun ev-fork-init (ev cb) 482 | (ev-init ev cb) 483 | (ev-fork-set ev)) 484 | 485 | (defun ev-cleanup-init (ev cb) 486 | (ev-init ev cb) 487 | (ev-cleanup-set ev)) 488 | 489 | (defun ev-async-init (ev cb) 490 | (ev-init ev cb) 491 | (ev-async-set ev)) 492 | 493 | (defun ev-is-pending (ev) 494 | (cffi:foreign-slot-value ev '(:struct ev-watcher) 'pending)) 495 | 496 | (defun ev-is-active (ev) 497 | (cffi:foreign-slot-value ev '(:struct ev-watcher) 'active)) 498 | 499 | (defun ev-cb (ev) 500 | (cffi:foreign-slot-value ev '(:struct ev-watcher) 'cb)) 501 | (defun (setf ev-cb) (cb ev) 502 | (setf (cffi:foreign-slot-value ev '(:struct ev-watcher) 'cb) cb)) 503 | 504 | (defun ev-set-cb (ev cb) 505 | (setf (ev-cb ev) cb)) 506 | 507 | #.(if (= +ev-minpri+ +ev-maxpri+) 508 | `(progn 509 | (defun ev-priority (ev) 510 | ,ev-minpri) 511 | (defun (setf ev-priority) (priority ev) 512 | (declare (ignore ev)) 513 | priority) 514 | (defun ev-set-priority (ev priority) 515 | (setf (ev-priority ev) priority))) 516 | `(progn 517 | (defun ev-priority (ev) 518 | (cffi:foreign-slot-value ev '(:struct ev-watcher) 'priority)) 519 | (defun (setf ev-priority) (priority ev) 520 | (setf (cffi:foreign-slot-value ev '(:struct ev-watcher) 'priority) priority)) 521 | (defun ev-set-priority (ev priority) 522 | (setf (ev-priority ev) priority)))) 523 | 524 | (defun ev-periodic-at (ev) 525 | (cffi:foreign-slot-value ev '(:struct ev-watcher-time) 'at)) 526 | 527 | (cffi:defcfun ("ev_feed_event" #.(lispify "ev_feed_event" 'function)) :void 528 | (loop :pointer) 529 | (w :pointer) 530 | (revents :int)) 531 | 532 | (cffi:defcfun ("ev_feed_fd_event" #.(lispify "ev_feed_fd_event" 'function)) :void 533 | (loop :pointer) 534 | (fd :int) 535 | (revents :int)) 536 | 537 | (cffi:defcfun ("ev_feed_signal" #.(lispify "ev_feed_signal" 'function)) :void 538 | (signum :int)) 539 | 540 | (cffi:defcfun ("ev_feed_signal_event" #.(lispify "ev_feed_signal_event" 'function)) :void 541 | (loop :pointer) 542 | (signum :int)) 543 | 544 | (cffi:defcfun ("ev_invoke" #.(lispify "ev_invoke" 'function)) :void 545 | (loop :pointer) 546 | (w :pointer) 547 | (revents :int)) 548 | 549 | (cffi:defcfun ("ev_clear_pending" #.(lispify "ev_clear_pending" 'function)) :int 550 | (loop :pointer) 551 | (w :pointer)) 552 | 553 | (cffi:defcfun ("ev_io_start" #.(lispify "ev_io_start" 'function)) :void 554 | (loop :pointer) 555 | (w :pointer)) 556 | (cffi:defcfun ("ev_io_stop" #.(lispify "ev_io_stop" 'function)) :void 557 | (loop :pointer) 558 | (w :pointer)) 559 | 560 | (cffi:defcfun ("ev_timer_start" #.(lispify "ev_timer_start" 'function)) :void 561 | (loop :pointer) 562 | (w :pointer)) 563 | (cffi:defcfun ("ev_timer_stop" #.(lispify "ev_timer_stop" 'function)) :void 564 | (loop :pointer) 565 | (w :pointer)) 566 | ;; stops if active and no repeat, restarts if active and repeating, starts if inactive and repeating 567 | (cffi:defcfun ("ev_timer_again" #.(lispify "ev_timer_again" 'function)) :void 568 | (loop :pointer) 569 | (w :pointer)) 570 | ;; return remaining time 571 | (cffi:defcfun ("ev_timer_remaining" #.(lispify "ev_timer_remaining" 'function)) :double 572 | (loop :pointer) 573 | (w :pointer)) 574 | 575 | #+lev-ev-periodic 576 | (progn 577 | (cffi:defcfun ("ev_periodic_start" #.(lispify "ev_periodic_start" 'function)) :void 578 | (loop :pointer) 579 | (w :pointer)) 580 | (cffi:defcfun ("ev_periodic_stop" #.(lispify "ev_periodic_stop" 'function)) :void 581 | (loop :pointer) 582 | (w :pointer)) 583 | (cffi:defcfun ("ev_periodic_again" #.(lispify "ev_periodic_again" 'function)) :void 584 | (loop :pointer) 585 | (w :pointer))) 586 | 587 | #+lev-ev-signal 588 | (progn 589 | ;; only supported in the default loop 590 | (cffi:defcfun ("ev_signal_start" #.(lispify "ev_signal_start" 'function)) :void 591 | (loop :pointer) 592 | (w :pointer)) 593 | (cffi:defcfun ("ev_signal_stop" #.(lispify "ev_signal_stop" 'function)) :void 594 | (loop :pointer) 595 | (w :pointer))) 596 | 597 | #+lev-ev-child 598 | (progn 599 | ;; only supported in the default loop 600 | (cffi:defcfun ("ev_child_start" #.(lispify "ev_child_start" 'function)) :void 601 | (loop :pointer) 602 | (w :pointer)) 603 | (cffi:defcfun ("ev_child_stop" #.(lispify "ev_child_stop" 'function)) :void 604 | (loop :pointer) 605 | (w :pointer))) 606 | 607 | #+lev-ev-stat 608 | (progn 609 | (cffi:defcfun ("ev_stat_start" #.(lispify "ev_stat_start" 'function)) :void 610 | (loop :pointer) 611 | (w :pointer)) 612 | (cffi:defcfun ("ev_stat_stop" #.(lispify "ev_stat_stop" 'function)) :void 613 | (loop :pointer) 614 | (w :pointer)) 615 | (cffi:defcfun ("ev_stat_stat" #.(lispify "ev_stat_stat" 'function)) :void 616 | (loop :pointer) 617 | (w :pointer))) 618 | 619 | #+lev-ev-idle 620 | (progn 621 | (cffi:defcfun ("ev_idle_start" #.(lispify "ev_idle_start" 'function)) :void 622 | (loop :pointer) 623 | (w :pointer)) 624 | (cffi:defcfun ("ev_idle_stop" #.(lispify "ev_idle_stop" 'function)) :void 625 | (loop :pointer) 626 | (w :pointer))) 627 | 628 | #+lev-ev-prepare 629 | (progn 630 | (cffi:defcfun ("ev_prepare_start" #.(lispify "ev_prepare_start" 'function)) :void 631 | (loop :pointer) 632 | (w :pointer)) 633 | (cffi:defcfun ("ev_prepare_stop" #.(lispify "ev_prepare_stop" 'function)) :void 634 | (loop :pointer) 635 | (w :pointer))) 636 | 637 | #+lev-ev-check 638 | (progn 639 | (cffi:defcfun ("ev_check_start" #.(lispify "ev_check_start" 'function)) :void 640 | (loop :pointer) 641 | (w :pointer)) 642 | (cffi:defcfun ("ev_check_stop" #.(lispify "ev_check_stop" 'function)) :void 643 | (loop :pointer) 644 | (w :pointer))) 645 | 646 | #+lev-ev-fork 647 | (progn 648 | (cffi:defcfun ("ev_fork_start" #.(lispify "ev_fork_start" 'function)) :void 649 | (loop :pointer) 650 | (w :pointer)) 651 | (cffi:defcfun ("ev_fork_stop" #.(lispify "ev_fork_stop" 'function)) :void 652 | (loop :pointer) 653 | (w :pointer))) 654 | 655 | #+lev-ev-cleanup 656 | (progn 657 | (cffi:defcfun ("ev_cleanup_start" #.(lispify "ev_cleanup_start" 'function)) :void 658 | (loop :pointer) 659 | (w :pointer)) 660 | (cffi:defcfun ("ev_cleanup_stop" #.(lispify "ev_cleanup_stop" 'function)) :void 661 | (loop :pointer) 662 | (w :pointer))) 663 | 664 | #+lev-ev-embed 665 | (progn 666 | ;; only supported when loop to be embedded is in fact embeddable 667 | (cffi:defcfun ("ev_embed_start" #.(lispify "ev_embed_start" 'function)) :void 668 | (loop :pointer) 669 | (w :pointer)) 670 | (cffi:defcfun ("ev_embed_stop" #.(lispify "ev_embed_stop" 'function)) :void 671 | (loop :pointer) 672 | (w :pointer)) 673 | (cffi:defcfun ("ev_embed_sweep" #.(lispify "ev_embed_sweep" 'function)) :void 674 | (loop :pointer) 675 | (w :pointer))) 676 | 677 | #+lev-ev-async 678 | (progn 679 | (cffi:defcfun ("ev_async_start" #.(lispify "ev_async_start" 'function)) :void 680 | (loop :pointer) 681 | (w :pointer)) 682 | (cffi:defcfun ("ev_async_stop" #.(lispify "ev_async_stop" 'function)) :void 683 | (loop :pointer) 684 | (w :pointer)) 685 | (cffi:defcfun ("ev_async_send" #.(lispify "ev_async_send" 'function)) :void 686 | (loop :pointer) 687 | (w :pointer))) 688 | 689 | #+lev-ev-compat3 690 | (progn 691 | (defconstant #.(lispify "EVLOOP_NONBLOCK" 'contant) #.(lispify "EVRUN_NOWAIT" 'constant)) 692 | (defconstant #.(lispify "EVLOOP_ONESHOT" 'constant) #.(lispify "EVRUN_ONCE" 'constant)) 693 | (defconstant #.(lispify "EVUNLOOP_CANCEL" 'constant) #.(lispify "EVBREAK_CANCEL" 'constant)) 694 | (defconstant #.(lispify "EVUNLOOP_ONE" 'constant) #.(lispify "EVBREAK_ONE" 'constant)) 695 | (defconstant #.(lispify "EVUNLOOP_ALL" 'constant) #.(lispify "EVBREAK_ALL" 'constant))) 696 | 697 | (cffi:defcfun ("ev_loop" #.(lispify "ev_loop" 'function)) :void 698 | (loop :pointer) 699 | (flags :int)) 700 | 701 | (cffi:defcfun ("ev_unloop" #.(lispify "ev_unloop" 'function)) :void 702 | (loop :pointer) 703 | (how :int)) 704 | 705 | (cffi:defcfun ("ev_default_destroy" #.(lispify "ev_default_destroy" 'function)) :void) 706 | 707 | (cffi:defcfun ("ev_default_fork" #.(lispify "ev_default_fork" 'function)) :void) 708 | 709 | (cffi:defcfun ("ev_loop_count" #.(lispify "ev_loop_count" 'function)) :unsigned-int 710 | (loop :pointer)) 711 | 712 | (cffi:defcfun ("ev_loop_depth" #.(lispify "ev_loop_depth" 'function)) :unsigned-int 713 | (loop :pointer)) 714 | 715 | (cffi:defcfun ("ev_loop_verify" #.(lispify "ev_loop_verify" 'function)) :void 716 | (loop :pointer)) 717 | --------------------------------------------------------------------------------