Open hmelder opened 4 months ago
I am guessing that Windows implementation follows epoll logic, at least in some parts. It also suffers from similar dispatch_muxnote
_t issue. It is easily reproduced from Foundation by making POST URL request with body larger than 64k (which outstands CURL buffer and makes it to request adding and removing read/write dispatch sources exactly as needed to step on this issue). Our Android team reported that 64k POST is also a working breaker for them.
It also suffers from similar dispatch_muxnote_t issue
Interesting. We have not encountered the issues on Windows, but I'll investigate that too.
Our Android team reported that 64k POST is also a working breaker for them.
Do you have a hotfix for this that's different from mine?
We workarounded it in Foundation by duplicating sockets with dup
. This sort of works, because a "new" socket makes a separate muxntote, no collision.
Here is the commit. I am wondering if it works for you as well. But, anyway, that is a pure hack, unfortunately. Not to mention that it is not applicable to Windows. It have to be fixed in Dispatch. Your patch seems to be looking in the right direction.
This sort of works, because a "new" socket makes a separate muxntote, no collision.
Huh forgot that this is actually guaranteed by the API on Linux :)
The new file descriptor number is guaranteed to be the lowest-numbered
file descriptor that was unused in the calling process.
Hi, we created this fix with dub in Foundation to fix the 64K problem but I'm not very happy with it. Mostly, because it leads to over usage of file descriptors in runtime.
Android limits FD count to 1024, which may sound reasonable for most applications. But in our application users can add a lot of accounts that will use separate connections and we see that some power users reach this limit from time to time :(
That's why we would be glad to see a fix for this issue in libdispatch 👍
Creating a dispatch source for a socket file descriptor, removing it, and re-adding it shortly after results in a reuse of the underlying
dispatch_muxnote_t
which was created with the first dispatch source. This happens on Ubuntu 23.10 and Android API 24,34.However, during registration of the new unote in
_dispatch_unote_register_muxed
https://github.com/apple/swift-corelibs-libdispatch/blob/542b7f32311680b11b6fc8fcb2576955460ba7da/src/event/event_epoll.c#L270-L272_dispatch_epoll_update
returnsENOENT
and the existing muxnote is in turn not correctly updated.Sometimes, this is because of https://github.com/apple/swift-corelibs-libdispatch/blob/542b7f32311680b11b6fc8fcb2576955460ba7da/src/event/event_epoll.c#L602-L611
EPOLLHUP
.I also noticed removal of muxnotes which still had an active reader or writer.
Here is a workaround that worked for us:
Here is an example on Android API 34 with head at 542b7f3.
```logcat 2024-07-02 14:33:26.479 30762-30762 com.exampl...objectivec com.example.helloobjectivec E [thread:531362555096] Resume Task! 2024-07-02 14:33:26.479 30762-30883 com.exampl...objectivec com.example.helloobjectivec E [thread:531362589848] Timer Callback for Session