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