@@ -56,18 +56,20 @@ static int mevent_pipefd[2];
56
56
static pthread_mutex_t mevent_lmutex = PTHREAD_MUTEX_INITIALIZER ;
57
57
58
58
struct mevent {
59
- void (* me_func )(int , enum ev_type , void * );
60
- int me_fd ;
61
- enum ev_type me_type ;
62
- void * me_param ;
63
- int me_cq ;
64
- int me_state ;
65
- int me_closefd ;
66
-
67
- LIST_ENTRY (mevent ) me_list ;
59
+ void (* me_func )(int , enum ev_type , void * );
60
+ int me_fd ;
61
+ enum ev_type me_type ;
62
+ void * me_param ;
63
+ int me_cq ;
64
+ int me_state ;
65
+
66
+ int closefd ;
67
+ LIST_ENTRY (mevent ) me_list ;
68
68
};
69
69
70
70
static LIST_HEAD (listhead , mevent ) global_head ;
71
+ /* List holds the mevent node which is requested to deleted */
72
+ static LIST_HEAD (del_listhead , mevent ) del_head ;
71
73
72
74
static void
73
75
mevent_qlock (void )
@@ -81,6 +83,12 @@ mevent_qunlock(void)
81
83
pthread_mutex_unlock (& mevent_lmutex );
82
84
}
83
85
86
+ static bool
87
+ is_dispatch_thread (void )
88
+ {
89
+ return (pthread_self () == mevent_tid );
90
+ }
91
+
84
92
static void
85
93
mevent_pipe_read (int fd , enum ev_type type , void * param )
86
94
{
@@ -138,15 +146,11 @@ static void
138
146
mevent_destroy (void )
139
147
{
140
148
struct mevent * mevp , * tmpp ;
141
- struct epoll_event ee ;
142
149
143
150
mevent_qlock ();
144
-
145
151
list_foreach_safe (mevp , & global_head , me_list , tmpp ) {
146
152
LIST_REMOVE (mevp , me_list );
147
- ee .events = mevent_kq_filter (mevp );
148
- ee .data .ptr = mevp ;
149
- epoll_ctl (epoll_fd , EPOLL_CTL_DEL , mevp -> me_fd , & ee );
153
+ epoll_ctl (epoll_fd , EPOLL_CTL_DEL , mevp -> me_fd , NULL );
150
154
151
155
if ((mevp -> me_type == EVF_READ ||
152
156
mevp -> me_type == EVF_READ_ET ||
@@ -158,6 +162,21 @@ mevent_destroy(void)
158
162
free (mevp );
159
163
}
160
164
165
+ /* the mevp in del_head was removed from epoll when add it
166
+ * to del_head already.
167
+ */
168
+ list_foreach_safe (mevp , & del_head , me_list , tmpp ) {
169
+ LIST_REMOVE (mevp , me_list );
170
+
171
+ if ((mevp -> me_type == EVF_READ ||
172
+ mevp -> me_type == EVF_READ_ET ||
173
+ mevp -> me_type == EVF_WRITE ||
174
+ mevp -> me_type == EVF_WRITE_ET ) &&
175
+ mevp -> me_fd != STDIN_FILENO )
176
+ close (mevp -> me_fd );
177
+
178
+ free (mevp );
179
+ }
161
180
mevent_qunlock ();
162
181
}
163
182
@@ -169,9 +188,9 @@ mevent_handle(struct epoll_event *kev, int numev)
169
188
170
189
for (i = 0 ; i < numev ; i ++ ) {
171
190
mevp = kev [i ].data .ptr ;
172
- /* XXX check for EV_ERROR ? */
173
191
174
- (* mevp -> me_func )(mevp -> me_fd , mevp -> me_type , mevp -> me_param );
192
+ if (mevp -> me_state )
193
+ (* mevp -> me_func )(mevp -> me_fd , mevp -> me_type , mevp -> me_param );
175
194
}
176
195
}
177
196
@@ -210,6 +229,7 @@ mevent_add(int tfd, enum ev_type type,
210
229
mevp -> me_type = type ;
211
230
mevp -> me_func = func ;
212
231
mevp -> me_param = param ;
232
+ mevp -> me_state = 1 ;
213
233
214
234
ee .events = mevent_kq_filter (mevp );
215
235
ee .data .ptr = mevp ;
@@ -267,23 +287,50 @@ mevent_disable(struct mevent *evp)
267
287
return ret ;
268
288
}
269
289
290
+ static void
291
+ mevent_add_to_del_list (struct mevent * evp , int closefd )
292
+ {
293
+ mevent_qlock ();
294
+ LIST_INSERT_HEAD (& del_head , evp , me_list );
295
+ mevent_qunlock ();
296
+
297
+ mevent_notify ();
298
+ }
299
+
300
+ static void
301
+ mevent_drain_del_list (void )
302
+ {
303
+ struct mevent * evp , * tmpp ;
304
+
305
+ mevent_qlock ();
306
+ list_foreach_safe (evp , & del_head , me_list , tmpp ) {
307
+ LIST_REMOVE (evp , me_list );
308
+ if (evp -> closefd ) {
309
+ close (evp -> me_fd );
310
+ }
311
+ free (evp );
312
+ }
313
+ mevent_qunlock ();
314
+ }
315
+
270
316
static int
271
317
mevent_delete_event (struct mevent * evp , int closefd )
272
318
{
273
- struct epoll_event ee ;
274
-
275
319
mevent_qlock ();
276
320
LIST_REMOVE (evp , me_list );
277
321
mevent_qunlock ();
322
+ evp -> me_state = 0 ;
323
+ evp -> closefd = closefd ;
278
324
279
- ee .events = mevent_kq_filter (evp );
280
- ee .data .ptr = evp ;
281
- epoll_ctl (epoll_fd , EPOLL_CTL_DEL , evp -> me_fd , & ee );
282
-
283
- if (closefd )
284
- close (evp -> me_fd );
285
-
286
- free (evp );
325
+ epoll_ctl (epoll_fd , EPOLL_CTL_DEL , evp -> me_fd , NULL );
326
+ if (!is_dispatch_thread ()) {
327
+ mevent_add_to_del_list (evp , closefd );
328
+ } else {
329
+ if (evp -> closefd ) {
330
+ close (evp -> me_fd );
331
+ }
332
+ free (evp );
333
+ }
287
334
return 0 ;
288
335
}
289
336
@@ -322,6 +369,8 @@ mevent_deinit(void)
322
369
{
323
370
mevent_destroy ();
324
371
close (epoll_fd );
372
+ if (mevent_pipefd [1 ] != 0 )
373
+ close (mevent_pipefd [1 ]);
325
374
}
326
375
327
376
void
@@ -366,9 +415,9 @@ mevent_dispatch(void)
366
415
* Handle reported events
367
416
*/
368
417
mevent_handle (eventlist , ret );
418
+ mevent_drain_del_list ();
369
419
370
420
suspend_mode = vm_get_suspend_mode ();
371
-
372
421
if ((suspend_mode != VM_SUSPEND_NONE ) &&
373
422
(suspend_mode != VM_SUSPEND_SYSTEM_RESET ) &&
374
423
(suspend_mode != VM_SUSPEND_SUSPEND ))
0 commit comments