1 /*
2  * Copyright (c) 2011 William Pitcock <nenolod@dereferenced.org>.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
9  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
12  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
14  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
15  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
16  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
17  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
18  * POSSIBILITY OF SUCH DAMAGE.
19  */
20 
21 #include "mowgli.h"
22 
23 void
mowgli_simple_eventloop_timeout_once(mowgli_eventloop_t * eventloop,int timeout)24 mowgli_simple_eventloop_timeout_once(mowgli_eventloop_t *eventloop, int timeout)
25 {
26 	time_t delay, currtime;
27 	int t;
28 
29 	return_if_fail(eventloop != NULL);
30 	return_if_fail(eventloop->eventloop_ops != NULL);
31 
32 	mowgli_eventloop_synchronize(eventloop);
33 
34 	currtime = mowgli_eventloop_get_time(eventloop);
35 	delay = mowgli_eventloop_next_timer(eventloop);
36 
37 	while (delay != -1 && delay <= currtime)
38 	{
39 		mowgli_eventloop_run_timers(eventloop);
40 		mowgli_eventloop_synchronize(eventloop);
41 
42 		currtime = mowgli_eventloop_get_time(eventloop);
43 		delay = mowgli_eventloop_next_timer(eventloop);
44 	}
45 
46 	if (timeout)
47 		t = timeout;
48 	else if (delay == -1)
49 		t = 5000; /* arbitrary 5 second default timeout */
50 	else
51 		t = (delay - currtime) * 1000;
52 
53 #ifdef DEBUG
54 	mowgli_log("delay: %ld, currtime: %ld, select period: %d", delay, currtime, t);
55 #endif
56 
57 	eventloop->eventloop_ops->select(eventloop, t);
58 }
59 
60 void
mowgli_simple_eventloop_run_once(mowgli_eventloop_t * eventloop)61 mowgli_simple_eventloop_run_once(mowgli_eventloop_t *eventloop)
62 {
63 	eventloop->eventloop_ops->timeout_once(eventloop, 0);
64 }
65 
66 void
mowgli_simple_eventloop_error_handler(mowgli_eventloop_t * eventloop,mowgli_eventloop_io_t * io,mowgli_eventloop_io_dir_t dir,void * userdata)67 mowgli_simple_eventloop_error_handler(mowgli_eventloop_t *eventloop, mowgli_eventloop_io_t *io, mowgli_eventloop_io_dir_t dir, void *userdata)
68 {
69 	mowgli_eventloop_pollable_t *pollable = mowgli_eventloop_io_pollable(io);
70 
71 	if (pollable != NULL)
72 		mowgli_pollable_destroy(eventloop, pollable);
73 }
74 
75 static void
mowgli_null_eventloop_pollsetup(mowgli_eventloop_t * eventloop)76 mowgli_null_eventloop_pollsetup(mowgli_eventloop_t *eventloop)
77 {
78 	return;
79 }
80 
81 static void
mowgli_null_eventloop_pollshutdown(mowgli_eventloop_t * eventloop)82 mowgli_null_eventloop_pollshutdown(mowgli_eventloop_t *eventloop)
83 {
84 	return;
85 }
86 
87 static void
mowgli_null_eventloop_destroy(mowgli_eventloop_t * eventloop,mowgli_eventloop_pollable_t * pollable)88 mowgli_null_eventloop_destroy(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable)
89 {
90 	return;
91 }
92 
93 static void
mowgli_null_eventloop_setselect(mowgli_eventloop_t * eventloop,mowgli_eventloop_pollable_t * pollable,mowgli_eventloop_io_dir_t dir,mowgli_eventloop_io_cb_t * event_function)94 mowgli_null_eventloop_setselect(mowgli_eventloop_t *eventloop, mowgli_eventloop_pollable_t *pollable, mowgli_eventloop_io_dir_t dir, mowgli_eventloop_io_cb_t *event_function)
95 {
96 	mowgli_log("null eventloop does not really do polling, events for pollable<%p> will be ignored", (void *) pollable);
97 
98 	switch (dir)
99 	{
100 	case MOWGLI_EVENTLOOP_IO_READ:
101 		pollable->read_function = event_function;
102 		break;
103 	case MOWGLI_EVENTLOOP_IO_WRITE:
104 		pollable->write_function = event_function;
105 		break;
106 	default:
107 		mowgli_log("unhandled pollable direction %d", dir);
108 		break;
109 	}
110 
111 	return;
112 }
113 
114 static void
mowgli_null_eventloop_select(mowgli_eventloop_t * eventloop,int time)115 mowgli_null_eventloop_select(mowgli_eventloop_t *eventloop, int time)
116 {
117 	for (; time > 999999; time -= 999999)
118 		usleep(999999);
119 	usleep(time);
120 }
121 
122 mowgli_eventloop_ops_t _mowgli_null_pollops =
123 {
124 	.timeout_once = mowgli_simple_eventloop_timeout_once,
125 	.run_once = mowgli_simple_eventloop_run_once,
126 	.pollsetup = mowgli_null_eventloop_pollsetup,
127 	.pollshutdown = mowgli_null_eventloop_pollshutdown,
128 	.setselect = mowgli_null_eventloop_setselect,
129 	.select = mowgli_null_eventloop_select,
130 	.destroy = mowgli_null_eventloop_destroy,
131 };
132