Skip to content

Commit fbb9aa8

Browse files
author
Anton Pogonets
committed
Update CDispatch from swift-4.1-branch
1 parent 1051065 commit fbb9aa8

18 files changed

+388
-110
lines changed

src/block.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ extern "C" {
109109
// The compiler hides the name of the function it generates, and changes it if
110110
// we try to reference it directly, but the linker still sees it.
111111
extern void DISPATCH_BLOCK_SPECIAL_INVOKE(void *)
112-
#ifdef __linux__
112+
#if defined(__linux__) || defined(__FreeBSD__)
113113
asm("___dispatch_block_create_block_invoke");
114114
#else
115115
asm("____dispatch_block_create_block_invoke");

src/event/event_config.h

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,14 @@
7676
#if DISPATCH_EVENT_BACKEND_KEVENT
7777
# if defined(EV_SET_QOS)
7878
# define DISPATCH_USE_KEVENT_QOS 1
79-
# ifndef KEVENT_FLAG_IMMEDIATE
80-
# define KEVENT_FLAG_IMMEDIATE 0x001
81-
# endif
82-
# ifndef KEVENT_FLAG_ERROR_EVENTS
83-
# define KEVENT_FLAG_ERROR_EVENTS 0x002
84-
# endif
8579
# else
8680
# define DISPATCH_USE_KEVENT_QOS 0
8781
# endif
8882

83+
# ifndef KEVENT_FLAG_ERROR_EVENTS
84+
# define KEVENT_FLAG_ERROR_EVENTS 0x002
85+
# endif
86+
8987
# ifdef NOTE_LEEWAY
9088
# define DISPATCH_HAVE_TIMER_COALESCING 1
9189
# else
@@ -106,6 +104,14 @@
106104
# define NOTE_FUNLOCK 0x00000100
107105
# endif
108106

107+
// FreeBSD's kevent does not support those
108+
# ifndef NOTE_ABSOLUTE
109+
# define NOTE_ABSOLUTE 0
110+
# endif
111+
# ifndef NOTE_EXITSTATUS
112+
# define NOTE_EXITSTATUS 0
113+
# endif
114+
109115
# if HAVE_DECL_NOTE_REAP
110116
# if defined(NOTE_REAP) && defined(__APPLE__)
111117
# undef NOTE_REAP
@@ -146,9 +152,15 @@
146152

147153
# define DISPATCH_HAVE_TIMER_QOS 0
148154
# define DISPATCH_HAVE_TIMER_COALESCING 0
149-
# define KEVENT_FLAG_IMMEDIATE 0x001
150155
#endif // !DISPATCH_EVENT_BACKEND_KEVENT
151156

157+
// These flags are used by dispatch generic code and
158+
// translated back by the various backends to similar semantics
159+
// hence must be defined even on non Darwin platforms
160+
#ifndef KEVENT_FLAG_IMMEDIATE
161+
# define KEVENT_FLAG_IMMEDIATE 0x001
162+
#endif
163+
152164
#ifdef EV_UDATA_SPECIFIC
153165
# define DISPATCH_EV_DIRECT (EV_UDATA_SPECIFIC|EV_DISPATCH)
154166
#else

src/event/event_epoll.c

Lines changed: 79 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,13 @@ typedef struct dispatch_muxnote_s {
4747
TAILQ_ENTRY(dispatch_muxnote_s) dmn_list;
4848
TAILQ_HEAD(, dispatch_unote_linkage_s) dmn_readers_head;
4949
TAILQ_HEAD(, dispatch_unote_linkage_s) dmn_writers_head;
50-
int dmn_fd;
51-
uint32_t dmn_ident;
52-
uint32_t dmn_events;
53-
int16_t dmn_filter;
54-
bool dmn_skip_outq_ioctl;
55-
bool dmn_skip_inq_ioctl;
50+
int dmn_fd;
51+
uint32_t dmn_ident;
52+
uint32_t dmn_events;
53+
uint16_t dmn_disarmed_events;
54+
int8_t dmn_filter;
55+
bool dmn_skip_outq_ioctl : 1;
56+
bool dmn_skip_inq_ioctl : 1;
5657
} *dispatch_muxnote_t;
5758

5859
typedef struct dispatch_epoll_timeout_s {
@@ -83,6 +84,13 @@ static struct dispatch_epoll_timeout_s _dispatch_epoll_timeout[] = {
8384

8485
#pragma mark dispatch_muxnote_t
8586

87+
DISPATCH_ALWAYS_INLINE
88+
static inline uint32_t
89+
_dispatch_muxnote_armed_events(dispatch_muxnote_t dmn)
90+
{
91+
return dmn->dmn_events & ~dmn->dmn_disarmed_events;
92+
}
93+
8694
DISPATCH_ALWAYS_INLINE
8795
static inline struct dispatch_muxnote_bucket_s *
8896
_dispatch_muxnote_bucket(uint32_t ident)
@@ -95,7 +103,7 @@ _dispatch_muxnote_bucket(uint32_t ident)
95103
DISPATCH_ALWAYS_INLINE
96104
static inline dispatch_muxnote_t
97105
_dispatch_muxnote_find(struct dispatch_muxnote_bucket_s *dmb,
98-
uint32_t ident, int16_t filter)
106+
uint32_t ident, int8_t filter)
99107
{
100108
dispatch_muxnote_t dmn;
101109
if (filter == EVFILT_WRITE) filter = EVFILT_READ;
@@ -143,7 +151,7 @@ _dispatch_muxnote_create(dispatch_unote_t du, uint32_t events)
143151
dispatch_muxnote_t dmn;
144152
struct stat sb;
145153
int fd = (int)du._du->du_ident;
146-
int16_t filter = du._du->du_filter;
154+
int8_t filter = du._du->du_filter;
147155
bool skip_outq_ioctl = false, skip_inq_ioctl = false;
148156
sigset_t sigmask;
149157

@@ -207,33 +215,27 @@ _dispatch_muxnote_create(dispatch_unote_t du, uint32_t events)
207215
#pragma mark dispatch_unote_t
208216

209217
static int
210-
_dispatch_epoll_update(dispatch_muxnote_t dmn, int op)
218+
_dispatch_epoll_update(dispatch_muxnote_t dmn, uint32_t events, int op)
211219
{
212220
dispatch_once_f(&epoll_init_pred, NULL, _dispatch_epoll_init);
213221
struct epoll_event ev = {
214-
.events = dmn->dmn_events,
222+
.events = events,
215223
.data = { .ptr = dmn },
216224
};
217225
return epoll_ctl(_dispatch_epfd, op, dmn->dmn_fd, &ev);
218226
}
219227

220-
bool
221-
_dispatch_unote_register(dispatch_unote_t du,
222-
DISPATCH_UNUSED dispatch_wlh_t wlh, dispatch_priority_t pri)
228+
DISPATCH_ALWAYS_INLINE
229+
static inline uint32_t
230+
_dispatch_unote_required_events(dispatch_unote_t du)
223231
{
224-
struct dispatch_muxnote_bucket_s *dmb;
225-
dispatch_muxnote_t dmn;
226232
uint32_t events = EPOLLFREE;
227233

228-
dispatch_assert(!_dispatch_unote_registered(du));
229-
du._du->du_priority = pri;
230-
231234
switch (du._du->du_filter) {
232235
case DISPATCH_EVFILT_CUSTOM_ADD:
233236
case DISPATCH_EVFILT_CUSTOM_OR:
234237
case DISPATCH_EVFILT_CUSTOM_REPLACE:
235-
du._du->du_wlh = DISPATCH_WLH_ANON;
236-
return true;
238+
return 0;
237239
case EVFILT_WRITE:
238240
events |= EPOLLOUT;
239241
break;
@@ -246,24 +248,41 @@ _dispatch_unote_register(dispatch_unote_t du,
246248
events |= EPOLLONESHOT;
247249
}
248250

251+
return events;
252+
}
253+
254+
bool
255+
_dispatch_unote_register(dispatch_unote_t du,
256+
DISPATCH_UNUSED dispatch_wlh_t wlh, dispatch_priority_t pri)
257+
{
258+
struct dispatch_muxnote_bucket_s *dmb;
259+
dispatch_muxnote_t dmn;
260+
uint32_t events = _dispatch_unote_required_events(du);
261+
262+
dispatch_assert(!_dispatch_unote_registered(du));
263+
du._du->du_priority = pri;
264+
249265
dmb = _dispatch_unote_muxnote_bucket(du);
250266
dmn = _dispatch_unote_muxnote_find(dmb, du);
251267
if (dmn) {
252-
events &= ~dmn->dmn_events;
253-
if (events) {
254-
dmn->dmn_events |= events;
255-
if (_dispatch_epoll_update(dmn, EPOLL_CTL_MOD) < 0) {
256-
dmn->dmn_events &= ~events;
268+
if (events & ~_dispatch_muxnote_armed_events(dmn)) {
269+
events |= _dispatch_muxnote_armed_events(dmn);
270+
if (_dispatch_epoll_update(dmn, events, EPOLL_CTL_MOD) < 0) {
257271
dmn = NULL;
272+
} else {
273+
dmn->dmn_events |= events;
274+
dmn->dmn_disarmed_events &= ~events;
258275
}
259276
}
260277
} else {
261278
dmn = _dispatch_muxnote_create(du, events);
262-
if (_dispatch_epoll_update(dmn, EPOLL_CTL_ADD) < 0) {
263-
_dispatch_muxnote_dispose(dmn);
264-
dmn = NULL;
265-
} else {
266-
TAILQ_INSERT_TAIL(dmb, dmn, dmn_list);
279+
if (dmn) {
280+
if (_dispatch_epoll_update(dmn, events, EPOLL_CTL_ADD) < 0) {
281+
_dispatch_muxnote_dispose(dmn);
282+
dmn = NULL;
283+
} else {
284+
TAILQ_INSERT_TAIL(dmb, dmn, dmn_list);
285+
}
267286
}
268287
}
269288

@@ -286,8 +305,13 @@ _dispatch_unote_resume(dispatch_unote_t du)
286305
{
287306
dispatch_muxnote_t dmn = _dispatch_unote_get_linkage(du)->du_muxnote;
288307
dispatch_assert(_dispatch_unote_registered(du));
308+
uint32_t events = _dispatch_unote_required_events(du);
289309

290-
_dispatch_epoll_update(dmn, EPOLL_CTL_MOD);
310+
if (events & dmn->dmn_disarmed_events) {
311+
dmn->dmn_disarmed_events &= ~events;
312+
events = _dispatch_muxnote_armed_events(dmn);
313+
_dispatch_epoll_update(dmn, events, EPOLL_CTL_MOD);
314+
}
291315
}
292316

293317
bool
@@ -314,17 +338,26 @@ _dispatch_unote_unregister(dispatch_unote_t du, DISPATCH_UNUSED uint32_t flags)
314338
dul->du_muxnote = NULL;
315339

316340
if (TAILQ_EMPTY(&dmn->dmn_readers_head)) {
317-
events &= (uint32_t)(~EPOLLIN);
341+
events &= (uint32_t)~EPOLLIN;
342+
if (dmn->dmn_disarmed_events & EPOLLIN) {
343+
dmn->dmn_disarmed_events &= (uint16_t)~EPOLLIN;
344+
dmn->dmn_events &= (uint32_t)~EPOLLIN;
345+
}
318346
}
319347
if (TAILQ_EMPTY(&dmn->dmn_writers_head)) {
320-
events &= (uint32_t)(~EPOLLOUT);
348+
events &= (uint32_t)~EPOLLOUT;
349+
if (dmn->dmn_disarmed_events & EPOLLOUT) {
350+
dmn->dmn_disarmed_events &= (uint16_t)~EPOLLOUT;
351+
dmn->dmn_events &= (uint32_t)~EPOLLOUT;
352+
}
321353
}
322354

323-
if (events == dmn->dmn_events) {
324-
// nothing to do
325-
} else if (events & (EPOLLIN | EPOLLOUT)) {
326-
dmn->dmn_events = events;
327-
_dispatch_epoll_update(dmn, EPOLL_CTL_MOD);
355+
if (events & (EPOLLIN | EPOLLOUT)) {
356+
if (events != _dispatch_muxnote_armed_events(dmn)) {
357+
dmn->dmn_events = events;
358+
events = _dispatch_muxnote_armed_events(dmn);
359+
_dispatch_epoll_update(dmn, events, EPOLL_CTL_MOD);
360+
}
328361
} else {
329362
epoll_ctl(_dispatch_epfd, EPOLL_CTL_DEL, dmn->dmn_fd, NULL);
330363
TAILQ_REMOVE(_dispatch_unote_muxnote_bucket(du), dmn, dmn_list);
@@ -358,13 +391,14 @@ _dispatch_timeout_program(uint32_t tidx, uint64_t target,
358391
dispatch_epoll_timeout_t timer = &_dispatch_epoll_timeout[clock];
359392
struct epoll_event ev = {
360393
.events = EPOLLONESHOT | EPOLLIN,
361-
.data = { .u32 = timer->det_ident },
394+
362395
};
363396
int op;
364397

365398
if (target >= INT64_MAX && !timer->det_registered) {
366399
return;
367400
}
401+
ev.data.u32 = timer->det_ident;
368402

369403
if (unlikely(timer->det_fd < 0)) {
370404
clockid_t clockid;
@@ -386,7 +420,7 @@ _dispatch_timeout_program(uint32_t tidx, uint64_t target,
386420

387421
if (target < INT64_MAX) {
388422
struct itimerspec its = { .it_value = {
389-
.tv_sec = target / NSEC_PER_SEC,
423+
.tv_sec = (time_t)(target / NSEC_PER_SEC),
390424
.tv_nsec = target % NSEC_PER_SEC,
391425
} };
392426
dispatch_assume_zero(timerfd_settime(timer->det_fd, TFD_TIMER_ABSTIME,
@@ -533,6 +567,8 @@ _dispatch_event_merge_fd(dispatch_muxnote_t dmn, uint32_t events)
533567
dispatch_unote_linkage_t dul, dul_next;
534568
uintptr_t data;
535569

570+
dmn->dmn_disarmed_events |= (events & (EPOLLIN | EPOLLOUT));
571+
536572
if (events & EPOLLIN) {
537573
data = _dispatch_get_buffer_size(dmn, false);
538574
TAILQ_FOREACH_SAFE(dul, &dmn->dmn_readers_head, du_link, dul_next) {
@@ -548,6 +584,9 @@ _dispatch_event_merge_fd(dispatch_muxnote_t dmn, uint32_t events)
548584
dux_merge_evt(du._du, EV_ADD|EV_ENABLE|EV_DISPATCH, ~data, 0, 0);
549585
}
550586
}
587+
588+
events = _dispatch_muxnote_armed_events(dmn);
589+
if (events) _dispatch_epoll_update(dmn, events, EPOLL_CTL_MOD);
551590
}
552591

553592
DISPATCH_NOINLINE

0 commit comments

Comments
 (0)