bpo-33021: Release the GIL during fstat() calls (GH-6019) · python/cpython@4484f9d (original) (raw)
3 files changed
lines changed
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
1 | +Release the GIL during fstat() calls, avoiding hang of all threads when | |
2 | +calling mmap.mmap(), os.urandom(), and random.seed(). Patch by Nir Soffer. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1050,6 +1050,7 @@ static PyObject * | ||
1050 | 1050 | new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) |
1051 | 1051 | { |
1052 | 1052 | struct _Py_stat_struct status; |
1053 | +int fstat_result; | |
1053 | 1054 | mmap_object *m_obj; |
1054 | 1055 | Py_ssize_t map_size; |
1055 | 1056 | off_t offset = 0; |
@@ -1115,8 +1116,14 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) | ||
1115 | 1116 | if (fd != -1) |
1116 | 1117 | (void)fcntl(fd, F_FULLFSYNC); |
1117 | 1118 | #endif |
1118 | -if (fd != -1 && _Py_fstat_noraise(fd, &status) == 0 | |
1119 | -&& S_ISREG(status.st_mode)) { | |
1119 | + | |
1120 | +if (fd != -1) { | |
1121 | +Py_BEGIN_ALLOW_THREADS | |
1122 | +fstat_result = _Py_fstat_noraise(fd, &status); | |
1123 | +Py_END_ALLOW_THREADS | |
1124 | + } | |
1125 | + | |
1126 | +if (fd != -1 && fstat_result == 0 && S_ISREG(status.st_mode)) { | |
1120 | 1127 | if (map_size == 0) { |
1121 | 1128 | if (status.st_size == 0) { |
1122 | 1129 | PyErr_SetString(PyExc_ValueError, |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -301,10 +301,15 @@ dev_urandom(char *buffer, Py_ssize_t size, int raise) | ||
301 | 301 | |
302 | 302 | if (raise) { |
303 | 303 | struct _Py_stat_struct st; |
304 | +int fstat_result; | |
304 | 305 | |
305 | 306 | if (urandom_cache.fd >= 0) { |
307 | +Py_BEGIN_ALLOW_THREADS | |
308 | +fstat_result = _Py_fstat_noraise(urandom_cache.fd, &st); | |
309 | +Py_END_ALLOW_THREADS | |
310 | + | |
306 | 311 | /* Does the fd point to the same thing as before? (issue #21207) */ |
307 | -if (_Py_fstat_noraise(urandom_cache.fd, &st) | |
312 | +if (fstat_result | |
308 | 313 | | |
309 | 314 | | |
310 | 315 | /* Something changed: forget the cached fd (but don't close it, |