1
Origin: commit:5daa29168df38b8b5f0f59b0c65a5740082e002a
2
Author: Ray Strode <rstrode@redhat.com>
3
Subject: [event-loop] Add reference count to event sources
5
This prevents the event loop from freeing sources
6
early in an iteration of the loop, and then dispatching
7
handlers for the source later in that same iteration.
9
Index: b/src/libply/ply-event-loop.c
10
===================================================================
11
--- a/src/libply/ply-event-loop.c
12
+++ b/src/libply/ply-event-loop.c
14
ply_list_t *fd_watches;
15
uint32_t is_getting_polled : 1;
16
uint32_t is_disconnected : 1;
17
+ int reference_count;
26
+ply_event_source_take_reference (ply_event_source_t *source)
28
+ source->reference_count++;
31
static ply_event_source_t *
32
ply_event_source_new (int fd)
35
source->fd_watches = ply_list_new ();
36
source->is_getting_polled = false;
37
source->is_disconnected = false;
38
+ source->reference_count = 0;
46
+ply_event_source_drop_reference (ply_event_source_t *source)
51
+ source->reference_count--;
53
+ assert (source->reference_count >= 0);
55
+ if (source->reference_count == 0)
57
+ ply_event_source_free (source);
62
ply_event_loop_update_source_event_mask (ply_event_loop_t *loop,
63
ply_event_source_t *source)
66
assert (source != NULL);
68
destination->source = source;
69
+ ply_event_source_take_reference (source);
70
destination_node = ply_list_append_data (source->destinations, destination);
71
assert (destination_node != NULL);
72
assert (destination->source == source);
75
watch = ply_fd_watch_new (destination);
77
+ ply_event_source_take_reference (source);
78
ply_list_append_data (source->fd_watches, watch);
82
assert (source != NULL);
84
ply_list_remove_data (source->destinations, destination);
85
+ ply_event_source_drop_reference (source);
86
assert (ply_list_find_node (source->destinations, destination) == NULL);
87
ply_event_loop_update_source_event_mask (loop, source);
91
source->is_getting_polled = true;
93
+ ply_event_source_take_reference (source);
94
ply_list_append_data (loop->sources, source);
100
ply_list_remove_node (loop->sources, source_node);
101
+ ply_event_source_drop_reference (source);
107
ply_trace ("source for fd %d is already disconnected", source->fd);
108
ply_list_remove_data (source->fd_watches, watch);
109
+ ply_event_source_drop_reference (source);
110
ply_fd_watch_free (watch);
114
ply_event_loop_remove_destination_by_fd_watch (loop, watch);
116
ply_list_remove_data (source->fd_watches, watch);
117
+ ply_event_source_drop_reference (source);
118
ply_fd_watch_free (watch);
119
ply_event_destination_free (destination);
123
ply_trace ("no more destinations remaing for fd %d, removing source", source->fd);
124
ply_event_loop_remove_source (loop, source);
125
- ply_trace ("freeing source for fd %d", source->fd);
126
- ply_event_source_free (source);
130
@@ -1083,6 +1112,7 @@
131
assert (watch != NULL);
132
ply_fd_watch_free (watch);
133
ply_list_remove_node (source->fd_watches, node);
134
+ ply_event_source_drop_reference (source);
138
@@ -1142,6 +1172,7 @@
139
ply_event_destination_free (destination);
141
ply_list_remove_node (source->destinations, node);
142
+ ply_event_source_drop_reference (source);
146
@@ -1169,9 +1200,6 @@
147
ply_trace ("removing source with fd %d from event loop", source->fd);
148
ply_event_loop_remove_source (loop, source);
149
ply_trace ("done removing source with fd %d from event loop", source->fd);
151
- ply_trace ("freeing source with fd %d", source->fd);
152
- ply_event_source_free (source);
156
@@ -1261,6 +1289,19 @@
158
while ((number_of_received_events < 0) && ((errno == EINTR) || (errno == EAGAIN)));
160
+ /* first reference all sources, so they stay alive for the duration of this
161
+ * iteration of the loop
163
+ for (i = 0; i < number_of_received_events; i++)
165
+ ply_event_source_t *source;
166
+ source = (ply_event_source_t *) (events[i].data.ptr);
168
+ ply_event_source_take_reference (source);
171
+ /* Then process the incoming events
173
for (i = 0; i < number_of_received_events; i++)
175
ply_event_source_t *source;
176
@@ -1293,6 +1334,17 @@
177
if (loop->should_exit)
181
+ /* Finally, kill off any unused sources
183
+ for (i = 0; i < number_of_received_events; i++)
185
+ ply_event_source_t *source;
187
+ source = (ply_event_source_t *) (events[i].data.ptr);
189
+ ply_event_source_drop_reference (source);