Skip to content

Instantly share code, notes, and snippets.

@jpf91 jpf91/gist:1064625
Created Jul 5, 2011

Embed
What would you like to do?
/**
* Original libev documentation:
* $(LINK2 http://pod.tst.eu/http://cvs.schmorp.de/_libev/ev.pod?pathrev=rel-3__9, version 3.9)
* $(LINK2 http://pod.tst.eu/http://cvs.schmorp.de/_libev/ev.pod?pathrev=rel-4__04, version 4.04)
* $(LINK2 http://pod.tst.eu/http://cvs.schmorp.de/_libev/ev.pod, most recent version)
*/
module jpf.c.libev;
/*
* libev native API header
*
* Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License ("GPL") version 2 or any later version,
* in which case the provisions of the GPL are applicable instead of
* the above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the BSD license, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file under
* either the BSD or the GPL.
*/
extern(C):
align(4):
//TODO: Better way to define default versions
//TODO: EV_FEATURES_* is not working
/*version = LIBEV4;
version = LIBEV3_COMPAT;*/
version = EV_MULTIPLICITY;
version = EV_PERIODIC_ENABLE;
version = EV_STAT_ENABLE;
version = EV_IDLE_ENABLE;
version = EV_FORK_ENABLE;
version = EV_EMBED_ENABLE;
version = EV_ASYNC_ENABLE;
version = EV_SIGNAL_ENABLE;
version = EV_CHILD_ENABLE;
version = EV_PREPARE_ENABLE;
version = EV_CHECK_ENABLE;
version = ENABLE_ADDITIONAL_FEATURES;
//version = EV_WALK_ENABLE; not yet
version(LIBEV4)
{
version = EV_CLEANUP_ENABLE;
}
import core.stdc.signal;
import core.stdc.config; //c_long
version(EV_STAT_ENABLE)
{
version(Windows)
{
import core.stdc.time;
static assert(false, "EV_STAT_ENABLE not supported on windows");
//import core.sys.windows.sys.types;
//import core.sys.windows.sys.stat;
}
else version(Posix)
{
import core.sys.posix.sys.stat;
}
else
{
static assert(false, "EV_STAT_ENABLE not supported on this platform");
}
}
/* support multiple event loops? */
version(EV_MULTIPLICITY)
{
/* TODO: These enum string are #defines in the C
* header. They're used in function definitions:
* void test(EV_P_ int hello)
* D string mixins don't work in this case!
*/
enum EV_P = "ev_loop_t* loop"; /* a loop as sole parameter in a declaration */
enum EV_P_ = "ev_loop_t* loop,"; /* a loop as first of multiple parameters */
enum EV_A = "loop"; /* a loop as sole argument to a function call */
enum EV_A_ = EV_A; /* a loop as first of multiple arguments */
enum EV_DEFAULT_UC = "ev_default_loop_uc()"; /* the default loop, if initialised, as sole arg */
enum EV_DEFAULT_UC_ = EV_DEFAULT_UC; /* the default loop as first of multiple arguments */
enum EV_DEFAULT = "ev_default_loop(0)"; /* the default loop as sole arg */
enum EV_DEFAULT_ = EV_DEFAULT; /* the default loop as first of multiple arguments */
}
else
{
static assert(false, "BUG: EV_MULTIPLICITY is required");
}
/*****************************************************************************/
alias double ev_tstamp;
struct ev_loop_t;
enum EV_MINIMAL = 0;
/* these priorities are inclusive, higher priorities will be invoked earlier */
enum EV_MINPRI = -2;
enum EV_MAXPRI = 2;
alias /*volatile*/ shared sig_atomic_t EV_ATOMIC_T;
/*****************************************************************************/
/* eventmask, revents, events... */
enum : uint
{
EV_UNDEF = 0xFFFFFFFF, /** guaranteed to be invalid */
EV_NONE = 0x00, /** no events */
EV_READ = 0x01, /** ev_io detected read will not block */
EV_WRITE = 0x02, /** ev_io detected write will not block */
EV__IOFDSET = 0x80, /** internal use only */
EV_IO = EV_READ, /** alias for type-detection */
EV_PERIODIC = 0x00000200, /** periodic timer timed out */
EV_SIGNAL = 0x00000400, /** signal was received */
EV_CHILD = 0x00000800, /** child/pid had status change */
EV_STAT = 0x00001000, /** stat data changed */
EV_IDLE = 0x00002000, /** event loop is idling */
EV_PREPARE = 0x00004000, /** event loop about to poll */
EV_CHECK = 0x00008000, /** event loop finished poll */
EV_EMBED = 0x00010000, /** embedded event loop needs sweep */
EV_FORK = 0x00020000, /** event loop resumed in child */
EV_ASYNC = 0x00040000, /** async intra-loop signal */
EV_CUSTOM = 0x01000000, /** for use by user code */
EV_ERROR = 0x80000000, /** sent when an error occurs */
}
version(LIBEV4)
{
enum : uint
{
EV_TIMER = 0x00000100, /** timer timed out */
EV_CLEANUP = 0x00040000, /** event loop resumed in child */
}
version(LIBEV3_COMPAT)
{
enum : uint
{
EV_TIMEOUT = EV_TIMER, /** pre 4.0 API compatibility */
}
}
}
else
{
enum : uint
{
EV_TIMEOUT = 0x00000100, /** timer timed out */
EV_TIMER = EV_TIMEOUT, /** alias for type-detection */
}
}
template EV_COMMON()
{
void* data; ///
}
version(LIBEV4)
{
enum EV_VERSION_MAJOR = 4; ///Libev D header version: 4
enum EV_VERSION_MINOR = 4; ///Libev D header version: 04
}
else
{
enum EV_VERSION_MAJOR = 3; ///Libev D header version: 3
enum EV_VERSION_MINOR = 9; ///Libev D header version: 9
}
template EV_CB_DECLARE(TYPE)
{
void function (ev_loop_t*, TYPE*, int) cb; ///
}
/*
* struct member types:
* private: you may look at them, but not change them,
* and they might not mean anything to you.
* ro: can be read anytime, but only changed when the watcher isn't active.
* rw: can be read and modified anytime, even when the watcher is active.
*
* some internal details that might be helpful for debugging:
*
* active is either 0, which means the watcher is not active,
* or the array index of the watcher (periodics, timers)
* or the array index + 1 (most other watchers)
* or simply 1 for watchers that aren't in some array.
* pending is either 0, in which case the watcher isn't,
* or the array index + 1 in the pendings array.
*/
static if(EV_MINPRI == EV_MAXPRI)
{
template EV_DECL_PRIORITY()
{
}
}
else
{
template EV_DECL_PRIORITY()
{
int priority; ///
}
}
/* shared by all watchers */
template EV_WATCHER(TYPE)
{
int active; /// private
int pending; /// private
mixin EV_DECL_PRIORITY; /// private
mixin EV_COMMON; /// rw
mixin EV_CB_DECLARE!(TYPE); /// private
}
template EV_WATCHER_LIST(TYPE)
{
mixin EV_WATCHER!(TYPE);
ev_watcher_list* next; /// private
}
template EV_WATCHER_TIME(TYPE)
{
mixin EV_WATCHER!(TYPE);
ev_tstamp at; /// private
}
/** base class, nothing to see here unless you subclass */
struct ev_watcher
{
mixin EV_WATCHER!(ev_watcher);
}
/** base class, nothing to see here unless you subclass */
struct ev_watcher_list
{
mixin EV_WATCHER_LIST!(ev_watcher_list);
}
/** base class, nothing to see here unless you subclass */
struct ev_watcher_time
{
mixin EV_WATCHER_TIME!(ev_watcher_time);
}
/** invoked when fd is either EV_READable or EV_WRITEable
revent EV_READ, EV_WRITE */
struct ev_io
{
mixin EV_WATCHER_LIST!(ev_io);
int fd; /** ro */
int events; /** ro */
}
/** invoked after a specific time, repeatable (based on monotonic clock)
revent EV_TIMEOUT */
struct ev_timer
{
mixin EV_WATCHER_TIME!(ev_timer);
ev_tstamp repeat; /** rw */
}
version(EV_PERIODIC_ENABLE)
{
/** invoked at some specific time, possibly repeating at regular intervals (based on UTC)
revent EV_PERIODIC */
struct ev_periodic
{
mixin EV_WATCHER_TIME!(ev_periodic);
ev_tstamp offset; /** rw */
ev_tstamp interval; /** rw */
ev_tstamp function(ev_periodic *w, ev_tstamp now) reschedule_cb; /** rw */
}
}
/** invoked when the given signal has been received
revent EV_SIGNAL */
struct ev_signal
{
mixin EV_WATCHER_LIST!(ev_signal);
int signum; /** ro */
}
/** invoked when sigchld is received and waitpid indicates the given pid
revent EV_CHILD
does not support priorities */
struct ev_child
{
mixin EV_WATCHER_LIST!(ev_child);
int flags; /** private */
int pid; /** ro */
int rpid; /** rw, holds the received pid */
int rstatus; /** rw, holds the exit status, use the macros from sys/wait.h */
}
version(EV_STAT_ENABLE)
{
version(Windows)
{
static assert(false, "EV_STAT_ENABLE not supported on windows");
// Maybe this should work? _stati64?
//static import stat = std.c.windows.stat;
//alias stat.stat_t ev_statdata;
}
else version(Posix)
{
static import stat = core.sys.posix.sys.stat;
alias stat.stat_t ev_statdata;
}
else
{
static assert(false, "EV_STAT_ENABLE not supported on this platform");
}
/** invoked each time the stat data changes for a given path
revent EV_STAT */
struct ev_stat
{
mixin EV_WATCHER_LIST!(ev_stat);
ev_timer timer; /** private */
ev_tstamp interval; /** ro */
const (char)* path; /** ro */
ev_statdata prev; /** ro */
ev_statdata attr; /** ro */
int wd; /** wd for inotify, fd for kqueue */
}
}
version(EV_IDLE_ENABLE)
{
/** invoked when the nothing else needs to be done, keeps the process from blocking
revent EV_IDLE */
struct ev_idle
{
mixin EV_WATCHER!(ev_idle);
}
}
/** invoked for each run of the mainloop, just before the blocking call
you can still change events in any way you like
revent EV_PREPARE */
struct ev_prepare
{
mixin EV_WATCHER!(ev_prepare);
}
/** invoked for each run of the mainloop, just after the blocking call
revent EV_CHECK */
struct ev_check
{
mixin EV_WATCHER!(ev_check);
}
version(EV_FORK_ENABLE)
{
/** the callback gets invoked before check in the child process when a fork was detected
revent EV_FORK */
struct ev_fork
{
mixin EV_WATCHER!(ev_fork);
}
}
version(LIBEV4)
{
version(EV_CLEANUP_ENABLE)
{
/** is invoked just before the loop gets destroyed
revent EV_CLEANUP */
struct ev_cleanup
{
mixin EV_WATCHER!(ev_cleanup);
}
}
}
version(EV_EMBED_ENABLE)
{
/** used to embed an event loop inside another
the callback gets invoked when the event loop has handled events, and can be 0 */
struct ev_embed
{
mixin EV_WATCHER!(ev_embed);
ev_loop_t *other; /** ro */
ev_io io; /** private */
ev_prepare prepare; /** private */
ev_check check; /** unused */
ev_timer timer; /** unused */
ev_periodic periodic; /** unused */
ev_idle idle; /** unused */
ev_fork fork; /** private */
version(LIBEV4)
{
version(EV_CLEANUP_ENABLE)
{
ev_cleanup cleanup; /** unused */
}
}
}
}
version(EV_ASYNC_ENABLE)
{
/** invoked when somebody calls ev_async_send on the watcher
revent EV_ASYNC */
struct ev_async
{
mixin EV_WATCHER!(ev_async);
EV_ATOMIC_T sent; /** private */
}
///
bool ev_async_pending(ev_async* watch)
{
if(watch.sent)
return true;
else
return false;
}
}
/+ ***************Not supported in D*****************
/* the presence of this union forces similar struct layout */
union ev_any_watcher
{
struct ev_watcher w;
struct ev_watcher_list wl;
struct ev_io io;
struct ev_timer timer;
struct ev_periodic periodic;
struct ev_signal signal;
struct ev_child child;
#if EV_STAT_ENABLE
struct ev_stat stat;
#endif
#if EV_IDLE_ENABLE
struct ev_idle idle;
#endif
struct ev_prepare prepare;
struct ev_check check;
#if EV_FORK_ENABLE
struct ev_fork fork;
#endif
+ LIBEV4 only
#if EV_CLEANUP_ENABLE
struct ev_cleanup cleanup;
#endif
+ End LIBEV4 only
#if EV_EMBED_ENABLE
struct ev_embed embed;
#endif
#if EV_ASYNC_ENABLE
struct ev_async async;
#endif
};
+/
enum : uint
{
/** flag bits for ev_default_loop and ev_loop_t_new
the default */
EVFLAG_AUTO = 0x00000000U, /** not quite a mask */
/** flag bits */
EVFLAG_NOENV = 0x01000000U, /** do NOT consult environment */
EVFLAG_FORKCHECK = 0x02000000U, /** check for a fork in each iteration */
/** debugging/feature disable */
EVFLAG_NOINOTIFY = 0x00100000U, /** do not attempt to use inotify */
EVFLAG_SIGNALFD = 0x00200000U, /** attempt to use signalfd */
/** method bits to be ored together */
EVBACKEND_SELECT = 0x00000001U, /** about anywhere */
EVBACKEND_POLL = 0x00000002U, /** !win */
EVBACKEND_EPOLL = 0x00000004U, /** linux */
EVBACKEND_KQUEUE = 0x00000008U, /** bsd */
EVBACKEND_DEVPOLL = 0x00000010U, /** solaris 8 */ /** NYI */
EVBACKEND_PORT = 0x00000020U, /** solaris 10 */
EVBACKEND_ALL = 0x0000003FU /** all known backends */
}
version(LIBEV4)
{
enum : uint
{
EVFLAG_NOSIGMASK = 0x00400000U, /** avoid modifying the signal mask */
EVBACKEND_MASK = 0x0000FFFFU /** all future backends */
}
version(LIBEV3_COMPAT)
{
enum : uint
{
EVFLAG_NOSIGFD = 0 /** compatibility to pre-3.9 */
}
}
}
else
{
enum : uint
{
EVFLAG_NOSIGFD = 0 /** compatibility to pre-3.9 */
}
}
int ev_version_major (); ///
int ev_version_minor (); ///
uint ev_supported_backends(); ///
uint ev_recommended_backends(); ///
uint ev_embeddable_backends(); ///
ev_tstamp ev_time(); ///
void ev_sleep (ev_tstamp delay); /** sleep for a while */
/** Sets the allocation function to use, works like realloc.
* It is used to allocate and free memory.
* If it returns zero when memory needs to be allocated, the library might abort
* or take some potentially destructive action.
* The default is your system realloc function.
*/
void ev_set_allocator(void* function(void* ptr, c_long size));
/** set the callback function to call on a
* retryable syscall error
* (such as failed select, poll, epoll_wait)
*/
void ev_set_syserr_cb(void function(const (char*) msg));
version(EV_MULTIPLICITY)
{
__gshared ev_loop_t* ev_default_loop_ptr;
ev_loop_t* ev_default_loop_uc()
{
return ev_default_loop_ptr;
}
version(LIBEV4)
{
ev_loop_t *ev_default_loop(uint flags);
}
else
{
ev_loop_t* ev_default_loop_init(uint flags);
/** the default loop is the only one that handles signals and child watchers
you can call this as often as you like */
ev_loop_t *ev_default_loop(uint flags)
{
ev_loop_t* loop = ev_default_loop_uc();
if (!loop)
{
loop = ev_default_loop_init(flags);
}
return loop;
}
}
/** create and destroy alternative loops that don't handle signals */
ev_loop_t* ev_loop_new (uint flags);
version(LIBEV4){}
else
{
void ev_loop_destroy (/*mixin(EV_P)*/ ev_loop_t* loop); ///ditto
void ev_loop_fork (/*mixin(EV_P)*/ ev_loop_t* loop); ///ditto
}
ev_tstamp ev_now (/*mixin(EV_P)*/ ev_loop_t* loop); /** time w.r.t. timers and the eventloop, updated after each poll */
}
else
{
//This part should work, but it's not tested:
static assert(false, "BUG: EV_MULTIPLICITY is required");
int ev_default_loop(uint flags); /** returns true when successful */
__gshared ev_tstamp ev_rt_now;
ev_tstamp ev_now() ///
{
return ev_rt_now;
}
}
int ev_is_default_loop(/*mixin(EV_P)*/ ev_loop_t* loop) ///
{
version(EV_MULTIPLICITY)
{
return !!(mixin(EV_A) == ev_default_loop_ptr);
}
else
return 1;
}
version(LIBEV4)
{
/** destroy event loops, also works for the default loop */
void ev_loop_destroy (/*mixin(EV_P)*/ ev_loop_t* loop);
/** this needs to be called after fork, to duplicate the loop
when you want to re-use it in the child
you can call it in either the parent or the child
you can actually call it at any time, anywhere :) */
void ev_loop_fork (/*mixin(EV_P)*/ ev_loop_t* loop);
}
else
{
void ev_default_destroy(); /** destroy the default loop */
/** this needs to be called after fork, to duplicate the default loop
* if you create alternative loops you have to call ev_loop_t_fork on them
* you can call it in either the parent or the child
* you can actually call it at any time, anywhere :) */
void ev_default_fork ();
}
uint ev_backend(/*mixin(EV_P)*/ ev_loop_t* loop); /** backend in use by loop */
void ev_now_update(/*mixin(EV_P)*/ ev_loop_t* loop); /** update event loop time */
version(EV_WALK_ENABLE)
{
/** walk (almost) all watchers in the loop of a given type, invoking the
* callback on every such watcher. The callback might stop the watcher,
* but do nothing else with the loop */
void ev_walk (/*mixin(EV_P_)*/ ev_loop_t* loop, int types, void function(/*mixin(EV_P_)*/ ev_loop_t* loop, int type, void* w));
}
version(LIBEV4)
{
/** ev_run flags values */
enum {
EVRUN_NOWAIT = 1, /** do not block/wait */
EVRUN_ONCE = 2 /** block *once* only */
}
/** ev_break how values */
enum {
EVBREAK_CANCEL = 0, /** undo unloop */
EVBREAK_ONE = 1, /** unloop once */
EVBREAK_ALL = 2 /** unloop all loops */
}
}
else
{
enum
{
EVLOOP_NONBLOCK =1, /** do not block/wait */
EVLOOP_ONESHOT = 2 /** block *once* only */
}
enum
{
EVUNLOOP_CANCEL = 0, /** undo unloop */
EVUNLOOP_ONE = 1, /** unloop once */
EVUNLOOP_ALL = 2 /** unloop all loops */
}
}
version(LIBEV4)
{
void ev_run (/*mixin(EV_P_)*/ ev_loop_t* loop, int flags); ///
void ev_break (/*mixin(EV_P_)*/ ev_loop_t* loop, int how); /** set to 1 to break out of event loop, set to 2 to break out of all event loops */
}
else
{
void ev_loop (/*mixin(EV_P_)*/ ev_loop_t* loop, int flags); ///
void ev_unloop (/*mixin(EV_P_)*/ ev_loop_t* loop, int how); /** set to 1 to break out of event loop, set to 2 to break out of all event loops */
}
/**
* ref/unref can be used to add or remove a refcount on the mainloop. every watcher
* keeps one reference. if you have a long-running watcher you never unregister that
* should not keep ev_loop_t from running, unref() after starting, and ref() before stopping.
*/
void ev_ref (/*mixin(EV_P)*/ ev_loop_t* loop);
void ev_unref (/*mixin(EV_P)*/ ev_loop_t* loop); ///ditto
/**
* convenience function, wait for a single event, without registering an event watcher
* if timeout is < 0, do wait indefinitely
*/
void ev_once (/*mixin(EV_P_)*/ ev_loop_t* loop, int fd, int events, ev_tstamp timeout, void function(int revents, void* arg), void *arg);
version(ENABLE_ADDITIONAL_FEATURES)
{
version(LIBEV4)
{
uint ev_iteration (/*mixin(EV_P)*/ ev_loop_t* loop); /** number of loop iterations */
uint ev_depth (/*mixin(EV_P)*/ ev_loop_t* loop); /** #ev_loop enters - #ev_loop leaves */
void ev_verify (/*mixin(EV_P)*/ ev_loop_t* loop); /** abort if loop data corrupted */
}
else
{
uint ev_loop_count (/*mixin(EV_P)*/ ev_loop_t* loop); /** number of loop iterations */
uint ev_loop_depth (/*mixin(EV_P)*/ ev_loop_t* loop); /** #ev_loop_t enters - #ev_loop_t leaves */
void ev_loop_verify (/*mixin(EV_P)*/ ev_loop_t* loop); /** abort if loop data corrupted */
}
void ev_set_io_collect_interval (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_tstamp interval); /** sleep at least this time, default 0 */
void ev_set_timeout_collect_interval (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_tstamp interval); /** sleep at least this time, default 0 */
/** advanced stuff for threading etc. support, see docs */
void ev_set_userdata (/*mixin(EV_P_)*/ ev_loop_t* loop, void *data);
///ditto
void *ev_userdata (/*mixin(EV_P)*/ ev_loop_t* loop);
///ditto
void ev_set_invoke_pending_cb (/*mixin(EV_P_)*/ ev_loop_t* loop, void function(/*mixin(EV_P)*/ ev_loop_t* loop) invoke_pending_cb);
///ditto
void ev_set_loop_release_cb (/*mixin(EV_P_)*/ ev_loop_t* loop, void function(/*mixin(EV_P)*/ ev_loop_t* loop) release, void function(/*mixin(EV_P)*/ ev_loop_t* loop) acquire);
uint ev_pending_count (/*mixin(EV_P)*/ ev_loop_t* loop); /** number of pending events, if any */
void ev_invoke_pending (/*mixin(EV_P)*/ ev_loop_t* loop); /** invoke all pending watchers */
/**
* stop/start the timer handling.
*/
void ev_suspend (/*mixin(EV_P)*/ ev_loop_t* loop);
///ditto
void ev_resume (/*mixin(EV_P)*/ ev_loop_t* loop);
}
/** these may evaluate ev multiple times, and the other arguments at most once
* either use ev_init + ev_TYPE_set, or the ev_TYPE_init macro, below, to first initialise a watcher */
void ev_init(TYPE)(TYPE* w, void function(ev_loop_t*, TYPE*, int) cb)
{
w.active = 0;
w.pending = 0;
ev_set_priority(w, 0);
ev_set_cb(w, cb);
}
///ditto
void ev_io_set(ev_io* w, int fd, int events)
{
w.fd = fd;
w.events = events | EV__IOFDSET;
}
///ditto
void ev_timer_set(ev_timer* w, ev_tstamp after, ev_tstamp repeat)
{
w.at = after;
w.repeat = repeat;
}
///ditto
void ev_periodic_set(ev_periodic* w, ev_tstamp ofs, ev_tstamp ival,
ev_tstamp function(ev_periodic *w, ev_tstamp now) res)
{
w.offset = ofs;
w.interval = ival;
w.reschedule_cb = res;
}
///ditto
void ev_signal_set(ev_signal* w, int signum)
{
w.signum = signum;
}
///ditto
void ev_child_set(ev_child* w, int pid, int trace)
{
w.pid = pid;
w.flags = !!trace;
}
///ditto
void ev_stat_set(ev_stat* w, char* path, ev_tstamp interval)
{
w.path = path;
w.interval = interval;
w.wd = -2;
}
///ditto
void ev_idle_set(ev_idle* w) /* nop, yes, this is a serious in-joke */
{
}
///ditto
void ev_prepare_set(ev_prepare* w) /* nop, yes, this is a serious in-joke */
{
}
///ditto
void ev_check_set(ev_check* w) /* nop, yes, this is a serious in-joke */
{
}
///ditto
void ev_embed_set(ev_embed* w, ev_loop_t* other)
{
w.other = other;
}
///ditto
void ev_fork_set(ev_fork* w) /* nop, yes, this is a serious in-joke */
{
}
version(LIBEV4)
{
version(EV_CLEANUP_ENABLE)
{
void ev_cleanup_set(ev_cleanup* w); /* nop, yes, this is a serious in-joke */
}
}
///ditto
void ev_async_set(ev_async* w) /* nop, yes, this is a serious in-joke */
{
}
///ditto
void ev_io_init(ev_io* w, void function(ev_loop_t*, ev_io*, int) cb, int fd,
int events)
{
ev_init(w, cb);
ev_io_set(w, fd, events);
}
///ditto
void ev_timer_init(ev_timer* w, void function(ev_loop_t*, ev_timer*, int) cb,
ev_tstamp after, ev_tstamp repeat)
{
ev_init(w, cb);
ev_timer_set(w, after, repeat);
}
///ditto
void ev_periodic_init(ev_periodic* w,
void function(ev_loop_t*, ev_periodic*, int) cb,
ev_tstamp ofs, ev_tstamp ival,
ev_tstamp function(ev_periodic *w, ev_tstamp now) res)
{
ev_init(w, cb);
ev_periodic_set(w, ofs, ival, res);
}
///ditto
void ev_signal_init(ev_signal* w, void function(ev_loop_t*, ev_signal*, int) cb,
int signum)
{
ev_init(w, cb);
ev_signal_set(w, signum);
}
///ditto
void ev_child_init(ev_child* w, void function(ev_loop_t*, ev_child*, int) cb,
int pid, int trace)
{
ev_init(w, cb);
ev_child_set(w, pid, trace);
}
///ditto
void ev_stat_init(ev_stat* w, void function(ev_loop_t*, ev_stat*, int) cb,
char* path, ev_tstamp interval)
{
ev_init(w, cb);
ev_stat_set(w, path, interval);
}
///ditto
void ev_idle_init(ev_idle* w, void function(ev_loop_t*, ev_idle*, int) cb)
{
ev_init(w, cb);
ev_idle_set(w);
}
///ditto
void ev_prepare_init(ev_prepare* w,
void function(ev_loop_t*, ev_prepare*, int) cb)
{
ev_init(w, cb);
ev_prepare_set(w);
}
///ditto
void ev_check_init(ev_check* w, void function(ev_loop_t*, ev_check*, int) cb)
{
ev_init(w, cb);
ev_check_set(w);
}
///ditto
void ev_embed_init(ev_embed* w, void function(ev_loop_t*, ev_embed*, int) cb,
ev_loop_t* other)
{
ev_init(w, cb);
ev_embed_set(w, other);
}
///ditto
void ev_fork_init(ev_fork* w, void function(ev_loop_t*, ev_fork*, int) cb)
{
ev_init(w, cb);
ev_fork_set(w);
}
version(LIBEV4)
{
version(EV_CLEANUP_ENABLE)
{
void ev_cleanup_init(ev_cleanup* w, void function(ev_loop_t*, ev_cleanup*, int) cb)
{
ev_init(w, cb);
ev_cleanup_set(w);
}
}
}
///ditto
void ev_async_init(ev_async* w, void function(ev_loop_t*, ev_async*, int) cb)
{
ev_init(w, cb);
ev_async_set(w);
}
///
bool ev_is_pending(TYPE)(TYPE* w)
{
return cast (bool) w.pending;
}
///
bool ev_is_active(TYPE)(TYPE* w)
{
return cast (bool) w.active;
}
///
void function(ev_loop_t*, TYPE*, int) ev_cb(TYPE)(TYPE* w)
{
return w.cb;
}
///
void ev_set_cb(TYPE)(TYPE* w,
void function(ev_loop_t*, TYPE*, int) cb)
{
w.cb = cb;
}
static if(EV_MINPRI == EV_MAXPRI)
{
///
int ev_priority(TYPE)(TYPE* w)
{
return EV_MINPRI;
}
///
void ev_set_priority(TYPE)(TYPE* w, int pri)
{
}
}
else
{
///
int ev_priority(TYPE)(TYPE* w)
{
return w.priority;
}
///
void ev_set_priority(TYPE)(TYPE* w, int pri)
{
static if(__traits(compiles, w.priority))
w.priority = pri;
}
}
///
ev_tstamp ev_periodic_at(ev_watcher_time* ev)
{
return ev.at;
}
/** feeds an event into a watcher as if the event actually occured
accepts any ev_watcher type */
void ev_feed_event (/*mixin(EV_P_)*/ ev_loop_t* loop, void *w, int revents);
void ev_feed_fd_event (/*mixin(EV_P_)*/ ev_loop_t* loop, int fd, int revents); ///ditto
version(EV_SIGNAL_ENABLE)
{
version(LIBEV4)
{
void ev_feed_signal (int signum);
}
void ev_feed_signal_event (/*mixin(EV_P_)*/ ev_loop_t* loop, int signum); ///ditto
}
void ev_invoke (/*mixin(EV_P_)*/ ev_loop_t* loop, void *w, int revents); ///ditto
int ev_clear_pending (/*mixin(EV_P_)*/ ev_loop_t* loop, void *w); ///ditto
/** stopping (enabling, adding) a watcher does nothing if it is already running
stopping (disabling, deleting) a watcher does nothing unless its already running */
void ev_io_start (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_io *w);
void ev_io_stop (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_io *w); ///ditto
void ev_timer_start (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_timer *w); ///
void ev_timer_stop (/*mixin(EV_P_)*/ ev_loop_t* loop,ev_timer *w); ///
/** stops if active and no repeat, restarts if active and repeating, starts if inactive and repeating */
void ev_timer_again (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_timer *w);
/** return remaining time */
ev_tstamp ev_timer_remaining (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_timer *w);
version(EV_PERIODIC_ENABLE)
{
void ev_periodic_start (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_periodic *w); ///
void ev_periodic_stop (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_periodic *w); ///
void ev_periodic_again (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_periodic *w); ///
}
version(EV_SIGNAL_ENABLE)
{
/** only supported in the default loop */
void ev_signal_start (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_signal *w);
void ev_signal_stop (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_signal *w); ///ditto
}
version(EV_CHILD_ENABLE)
{
/** only supported in the default loop */
void ev_child_start (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_child *w);
void ev_child_stop (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_child *w); ///ditto
}
version(EV_STAT_ENABLE)
{
void ev_stat_start (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_stat *w); ///
void ev_stat_stop (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_stat *w); ///
void ev_stat_stat (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_stat *w); ///
}
version(EV_IDLE_ENABLE)
{
void ev_idle_start (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_idle *w); ///
void ev_idle_stop (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_idle *w); ///
}
version(EV_PREPARE_ENABLE)
{
void ev_prepare_start (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_prepare *w); ///
void ev_prepare_stop (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_prepare *w); ///
}
version(EV_CHECK_ENABLE)
{
void ev_check_start (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_check *w); ///
void ev_check_stop (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_check *w); ///
}
version(EV_FORK_ENABLE)
{
void ev_fork_start (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_fork *w); ///
void ev_fork_stop (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_fork *w); ///
}
version(LIBEV4)
{
version(EV_CLEANUP_ENABLE)
{
void ev_cleanup_start (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_cleanup *w);
void ev_cleanup_stop (/*mixin(EV_P_)*/ ev_loop_t* loop,ev_cleanup *w);
}
}
version(EV_EMBED_ENABLE)
{
/** only supported when loop to be embedded is in fact embeddable */
void ev_embed_start (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_embed *w);
void ev_embed_stop (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_embed *w); ///ditto
void ev_embed_sweep (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_embed *w); ///ditto
}
version(EV_ASYNC_ENABLE)
{
void ev_async_start (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_async *w); ///
void ev_async_stop (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_async *w); ///
void ev_async_send (/*mixin(EV_P_)*/ ev_loop_t* loop, ev_async *w); ///
}
version(LIBEV4)
{
version(LIBEV3_COMPAT)
{
alias EVRUN_NOWAIT EVLOOP_NONBLOCK;
alias EVRUN_ONCE EVLOOP_ONESHOT;
alias EVBREAK_CANCEL EVUNLOOP_CANCEL;
alias EVBREAK_ONE EVUNLOOP_ONE;
alias EVBREAK_ALL EVUNLOOP_ALL;
alias ev_run ev_loop;
alias ev_break ev_unloop;
alias ev_loop_destroy ev_default_destroy;
alias ev_loop_fork ev_default_fork;
version(ENABLE_ADDITIONAL_FEATURES)
{
alias ev_iteration ev_loop_count;
alias ev_depth ev_loop_depth;
alias ev_verify ev_loop_verify;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.