Skip to content

[SR-14920] CFRunLoop reads 8 bytes from each file descriptor it listens on Linux #3953

Open
@swift-ci

Description

@swift-ci
Previous ID SR-14920
Radar rdar://problem/80820393
Original Reporter PALKOVNIK (JIRA User)
Type Bug

Attachment: Download

Environment

Any swift version. I've noticed the issue in swift 5.1 or something like that, but based on the code it was present since the original support of Linux's epoll was introduced in CFRunLoop.

Additional Detail from JIRA
Votes 1
Component/s Foundation
Labels Bug
Assignee None
Priority Medium

md5: 5d0bc6cdfdf95adc92e299ec86b5ecdc

Issue Description:

CFRunLoop on Linux is using epoll on order to wait for events on "ports", which are just file descriptors on Linux. This includes the port used to wake up run loop. In order to tell run loop that it's awoken the code writes value of `1` as 8 byte integer into the wake up file descriptor and to "reset" the file descriptor state the code reads same 8 byte integer from it. The issue is in the fact that client code can register custom CFRunLoopSource with run loop and the code in run loop itself would read the same 8 bytes from the underlying file descriptor as if it would the wake up file descriptor.
I've prepared a very small sample project to reproduce the issue (it's a tiny part of my pet project) that can be found in attached archive. Jut do `swift run` on any Linux machine with `libx11-dev` installed and click few buttons on the keyboard in the window created by the app. xlib will abort execution saying
```
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
```
xlib is capable to understand that there's incorrect amount of data read from it's connection file descriptor and abort execution

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions