diff options
| author | Přemysl Janouch <p.janouch@gmail.com> | 2014-09-23 23:31:00 +0200 | 
|---|---|---|
| committer | Přemysl Janouch <p.janouch@gmail.com> | 2014-09-24 00:11:44 +0200 | 
| commit | eee873e373b44fd7fbdfdc67f043205b2d22e155 (patch) | |
| tree | 116b327d012e0aca42a3d674a1f6f5cc9bb918f4 | |
| parent | 19491375f3d14f169fa1717e0a320e2860c41772 (diff) | |
| download | ponymap-eee873e373b44fd7fbdfdc67f043205b2d22e155.tar.gz ponymap-eee873e373b44fd7fbdfdc67f043205b2d22e155.tar.xz ponymap-eee873e373b44fd7fbdfdc67f043205b2d22e155.zip | |
Implement idle events
| -rw-r--r-- | utils.c | 63 | 
1 files changed, 61 insertions, 2 deletions
| @@ -851,6 +851,7 @@ xclose (int fd)  typedef void (*poller_fd_fn) (const struct pollfd *, void *);  typedef void (*poller_timer_fn) (void *); +typedef void (*poller_idle_fn) (void *);  #define POLLER_MIN_ALLOC 16 @@ -877,6 +878,16 @@ struct poller_fd  	void *user_data;                    ///< User data  }; +struct poller_idle +{ +	LIST_HEADER (poller_idle) +	struct poller *poller;              ///< Our poller +	bool active;                        ///< Whether we're on the list + +	poller_idle_fn dispatcher;          ///< Event dispatcher +	void *user_data;                    ///< User data +}; +  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  struct poller_timers @@ -1023,6 +1034,19 @@ poller_timers_get_poll_timeout (struct poller_timers *self)  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +static void +poller_idle_dispatch (struct poller_idle *list) +{ +	struct poller_idle *iter, *next; +	for (iter = list; iter; iter = next) +	{ +		next = iter->next; +		iter->dispatcher (iter->user_data); +	} +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +  #ifdef __linux__  #include <sys/epoll.h> @@ -1035,6 +1059,7 @@ struct poller  	size_t alloc;                       ///< Number of entries allocated  	struct poller_timers timers;        ///< Timeouts +	struct poller_idle *idle;           ///< Idle events  	/// Index of the element in `revents' that's about to be dispatched next.  	int dispatch_next; @@ -1181,7 +1206,7 @@ poller_run (struct poller *self)  	int n_fds;  	do  		n_fds = epoll_wait (self->epoll_fd, self->revents, self->len, -			poller_timers_get_poll_timeout (&self->timers)); +			self->idle ? 0 : poller_timers_get_poll_timeout (&self->timers));  	while (n_fds == -1 && errno == EINTR);  	if (n_fds == -1) @@ -1191,6 +1216,7 @@ poller_run (struct poller *self)  	self->dispatch_total = n_fds;  	poller_timers_dispatch (&self->timers); +	poller_idle_dispatch (self->idle);  	while (self->dispatch_next < self->dispatch_total)  	{ @@ -1220,6 +1246,7 @@ struct poller  	size_t alloc;                       ///< Number of entries allocated  	struct poller_timers timers;        ///< Timers +	struct poller_idle *idle;           ///< Idle events  	int dispatch_next;                  ///< The next dispatched FD or -1  }; @@ -1309,13 +1336,14 @@ poller_run (struct poller *self)  	int result;  	do  		result = poll (self->fds, self->len, -			poller_timers_get_poll_timeout (&self->timers)); +			self->idle ? 0 : poller_timers_get_poll_timeout (&self->timers));  	while (result == -1 && errno == EINTR);  	if (result == -1)  		exit_fatal ("%s: %s", "poll", strerror (errno));  	poller_timers_dispatch (&self->timers); +	poller_idle_dispatch (self->idle);  	for (int i = 0; i < (int) self->len; )  	{ @@ -1359,6 +1387,37 @@ poller_timer_reset (struct poller_timer *self)  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  static void +poller_idle_init (struct poller_idle *self, struct poller *poller) +{ +	memset (self, 0, sizeof *self); +	self->poller = poller; +} + +static void +poller_idle_set (struct poller_idle *self) +{ +	if (self->active) +		return; + +	LIST_PREPEND (self->poller->idle, self); +	self->active = true; +} + +static void +poller_idle_reset (struct poller_idle *self) +{ +	if (!self->active) +		return; + +	LIST_UNLINK (self->poller->idle, self); +	self->prev = NULL; +	self->next = NULL; +	self->active = false; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +static void  poller_fd_init (struct poller_fd *self, struct poller *poller, int fd)  {  	memset (self, 0, sizeof *self); | 
