GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — gh-151707: fix race conditions in `FileIO` by KowalskiThomas · Pull Request #151708 · python/cpython Conversation
|
| static inline void | |
| set_sock_fd(PySocketSockObject *s, SOCKET_T fd) | |
| { | |
| #if SIZEOF_SOCKET_T == SIZEOF_INT | |
| _Py_atomic_store_int_relaxed((int *)&s->sock_fd, (int)fd); | |
| #elif SIZEOF_SOCKET_T == SIZEOF_LONG | |
| _Py_atomic_store_long_relaxed((long *)&s->sock_fd, (long)fd); | |
| #elif SIZEOF_SOCKET_T == SIZEOF_LONG_LONG | |
| _Py_atomic_store_llong_relaxed((long long *)&s->sock_fd, (long long)fd); | |
| #else | |
| #error "Unsupported SIZEOF_SOCKET_T" | |
| #endif | |
| } | |
| static inline SOCKET_T | |
| get_sock_fd(PySocketSockObject *s) | |
| { | |
| #if SIZEOF_SOCKET_T == SIZEOF_INT | |
| return (SOCKET_T)_Py_atomic_load_int_relaxed((int *)&s->sock_fd); | |
| #elif SIZEOF_SOCKET_T == SIZEOF_LONG | |
| return (SOCKET_T)_Py_atomic_load_long_relaxed((long *)&s->sock_fd); | |
| #elif SIZEOF_SOCKET_T == SIZEOF_LONG_LONG | |
| return (SOCKET_T)_Py_atomic_load_llong_relaxed((long long *)&s->sock_fd); | |
| #else | |
| #error "Unsupported SIZEOF_SOCKET_T" | |
| #endif | |
| } |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that it's the right approach. While the change makes sure that int fd integer is not modified in parallel, it doesn't ensure that the file descriptor is not closed before/while we are using it.
For example, FileIO.isatty() gets int fd, check that it's >= 0, and then call isatty().
If another thread calls close(fd) in parallel, after >= 0 check and before isatty() call, isatty() fails with EBADF.
It's even worse if the file descriptor is recycled for a new unrelated file.
Maybe it would be safer to the whole method in a critical section. It would prevent calling FileIO.close() in parallel: the call would be serialized.
@cmaloney: What do you think?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Oh, the TSan tests failed. Example: |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
I guess we have an answer 😁 |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
This PR is stale because it has been open for 90 days with no activity. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
I'm going to close this PR as I'm working (in an issue I'll post soon) on a better way to make |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
Race condition inFileIO under free-threading
There was an error while loading. Please reload this page.