There was a report on the xdispatch mailing list concerning a bug in
libkqueue discovered when re-using a socket fd within different dispatch
source objects [1].
You can find the detailed description below. From my understanding the
desired behaviour should not be an error but the old event should be
overridden, as documented in the man pages [2]:
>/ EV_ADD Adds the event to the kqueue. Re-adding an existing event will modify the parameters of
/>/ the original event, and not result in a duplicate entry. Adding an event automatically
/>/ enables it, unless overridden by the EV_DISABLE flag./
I will try to create a unit test exposing that bug and hopefully showing
the behaviour on Mac OS X. What's your opinion on that?
--
Marius Zwicker B.Sc.
MLBA - TEAM
www.mlba-team.de
PGP 8843 4AEF 1993 DD73 9358 22A1 9FBB 936E E09F 097D
X.509 C3:23:E9:B3:C1:23:4F:A6:20:DF:86:A8:7B:30:9E:30:49:C5:9E:53
[1]
http://opensource.mlba-team.de/pipermail/libxdispatch/2012-September/000049.html
[2]
https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man2/kqueue.2.html
We are using xdispatch for some worthy causes and encountered a rather bad
(from functionality standpoiont) breakage in libkqueue.
Namely, when try to associate multiple sources with a single socket file
descriptor, libkqueue breaks badly, the best case being this assertion:
----
bug1: xdispatch_0.7.0_src/libkqueue/src/common/knote.c:65:
void knote_release(struct knote *): Assertion
`(&kn->kn_mtx)->mtx_status == 1 && pthread_equal((&kn->kn_mtx)->mtx_owner,
(pthread_self()))' failed.
----
Our usage pattern should be perfectly valid and rather common:
-----
int sock_fd;
...
...
disp_read = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, sock_fd,
0, conn->queue);
...
disp_write = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, sock_fd,
0, conn->queue);
-----
What really leads to that assertion, as far as we can see, is shortcoming
in libkqueue design, as indicated by the following error:
----
KQ [47334214375184]: epoll_update(): op=1 fd=6 events= { data = 0x1301310,
events = EPOLLOUT EPOLLONESHOT }
KQ [47334214375184]: epoll_update(): epoll_ctl(2): File exists
----
It appears, that libkqueue always does EPOLL_CTL_ADD when event is registered,
even when the proper operation will be EPOLL_CTL_MOD with appropriate arguments.