@@ -1124,18 +1124,18 @@ _Py_fopen_obj(PyObject *path, const char *mode)
1124
1124
}
1125
1125
1126
1126
/* Read count bytes from fd into buf.
1127
- *
1128
- * On success, return the number of read bytes, it can be lower than count.
1129
- * If the current file offset is at or past the end of file, no bytes are read,
1130
- * and read() returns zero.
1131
- *
1132
- * On error, raise an exception, set errno and return -1.
1133
- *
1134
- * When interrupted by a signal (read() fails with EINTR), retry the syscall.
1135
- * If the Python signal handler raises an exception, the function returns -1
1136
- * (the syscall is not retried).
1137
- *
1138
- * The GIL must be held . */
1127
+
1128
+ On success, return the number of read bytes, it can be lower than count.
1129
+ If the current file offset is at or past the end of file, no bytes are read,
1130
+ and read() returns zero.
1131
+
1132
+ On error, raise an exception, set errno and return -1.
1133
+
1134
+ When interrupted by a signal (read() fails with EINTR), retry the syscall.
1135
+ If the Python signal handler raises an exception, the function returns -1
1136
+ (the syscall is not retried).
1137
+
1138
+ Release the GIL to call read(). The caller must hold the GIL . */
1139
1139
Py_ssize_t
1140
1140
_Py_read (int fd , void * buf , size_t count )
1141
1141
{
@@ -1200,34 +1200,20 @@ _Py_read(int fd, void *buf, size_t count)
1200
1200
return n ;
1201
1201
}
1202
1202
1203
- /* Write count bytes of buf into fd.
1204
- *
1205
- * -On success, return the number of written bytes, it can be lower than count
1206
- * including 0
1207
- * - On error, raise an exception, set errno and return -1.
1208
- *
1209
- * When interrupted by a signal (write() fails with EINTR), retry the syscall.
1210
- * If the Python signal handler raises an exception, the function returns -1
1211
- * (the syscall is not retried).
1212
- *
1213
- * The GIL must be held. */
1214
- Py_ssize_t
1215
- _Py_write (int fd , const void * buf , size_t count )
1203
+ static Py_ssize_t
1204
+ _Py_write_impl (int fd , const void * buf , size_t count , int gil_held )
1216
1205
{
1217
1206
Py_ssize_t n ;
1218
1207
int err ;
1219
1208
int async_err = 0 ;
1220
1209
1221
- /* _Py_write() must not be called with an exception set, otherwise the
1222
- * caller may think that write() was interrupted by a signal and the signal
1223
- * handler raised an exception. */
1224
- assert (!PyErr_Occurred ());
1225
-
1226
1210
if (!_PyVerify_fd (fd )) {
1227
- /* save/restore errno because PyErr_SetFromErrno() can modify it */
1228
- err = errno ;
1229
- PyErr_SetFromErrno (PyExc_OSError );
1230
- errno = err ;
1211
+ if (gil_held ) {
1212
+ /* save/restore errno because PyErr_SetFromErrno() can modify it */
1213
+ err = errno ;
1214
+ PyErr_SetFromErrno (PyExc_OSError );
1215
+ errno = err ;
1216
+ }
1231
1217
return -1 ;
1232
1218
}
1233
1219
@@ -1249,37 +1235,86 @@ _Py_write(int fd, const void *buf, size_t count)
1249
1235
}
1250
1236
#endif
1251
1237
1252
- do {
1253
- Py_BEGIN_ALLOW_THREADS
1254
- errno = 0 ;
1238
+ if (gil_held ) {
1239
+ do {
1240
+ Py_BEGIN_ALLOW_THREADS
1241
+ errno = 0 ;
1255
1242
#ifdef MS_WINDOWS
1256
- n = write (fd , buf , (int )count );
1243
+ n = write (fd , buf , (int )count );
1257
1244
#else
1258
- n = write (fd , buf , count );
1245
+ n = write (fd , buf , count );
1259
1246
#endif
1260
- /* save/restore errno because PyErr_CheckSignals()
1261
- * and PyErr_SetFromErrno() can modify it */
1262
- err = errno ;
1263
- Py_END_ALLOW_THREADS
1264
- } while (n < 0 && errno == EINTR &&
1265
- !(async_err = PyErr_CheckSignals ()));
1247
+ /* save/restore errno because PyErr_CheckSignals()
1248
+ * and PyErr_SetFromErrno() can modify it */
1249
+ err = errno ;
1250
+ Py_END_ALLOW_THREADS
1251
+ } while (n < 0 && err == EINTR &&
1252
+ !(async_err = PyErr_CheckSignals ()));
1253
+ }
1254
+ else {
1255
+ do {
1256
+ errno = 0 ;
1257
+ #ifdef MS_WINDOWS
1258
+ n = write (fd , buf , (int )count );
1259
+ #else
1260
+ n = write (fd , buf , count );
1261
+ #endif
1262
+ err = errno ;
1263
+ } while (n < 0 && err == EINTR );
1264
+ }
1266
1265
1267
1266
if (async_err ) {
1268
1267
/* write() was interrupted by a signal (failed with EINTR)
1269
- * and the Python signal handler raised an exception */
1268
+ and the Python signal handler raised an exception (if gil_held is
1269
+ nonzero). */
1270
1270
errno = err ;
1271
- assert (errno == EINTR && PyErr_Occurred ());
1271
+ assert (errno == EINTR && (! gil_held || PyErr_Occurred () ));
1272
1272
return -1 ;
1273
1273
}
1274
1274
if (n < 0 ) {
1275
- PyErr_SetFromErrno (PyExc_OSError );
1275
+ if (gil_held )
1276
+ PyErr_SetFromErrno (PyExc_OSError );
1276
1277
errno = err ;
1277
1278
return -1 ;
1278
1279
}
1279
1280
1280
1281
return n ;
1281
1282
}
1282
1283
1284
+ /* Write count bytes of buf into fd.
1285
+
1286
+ On success, return the number of written bytes, it can be lower than count
1287
+ including 0. On error, raise an exception, set errno and return -1.
1288
+
1289
+ When interrupted by a signal (write() fails with EINTR), retry the syscall.
1290
+ If the Python signal handler raises an exception, the function returns -1
1291
+ (the syscall is not retried).
1292
+
1293
+ Release the GIL to call write(). The caller must hold the GIL. */
1294
+ Py_ssize_t
1295
+ _Py_write (int fd , const void * buf , size_t count )
1296
+ {
1297
+ /* _Py_write() must not be called with an exception set, otherwise the
1298
+ * caller may think that write() was interrupted by a signal and the signal
1299
+ * handler raised an exception. */
1300
+ assert (!PyErr_Occurred ());
1301
+
1302
+ return _Py_write_impl (fd , buf , count , 1 );
1303
+ }
1304
+
1305
+ /* Write count bytes of buf into fd.
1306
+ *
1307
+ * On success, return the number of written bytes, it can be lower than count
1308
+ * including 0. On error, set errno and return -1.
1309
+ *
1310
+ * When interrupted by a signal (write() fails with EINTR), retry the syscall
1311
+ * without calling the Python signal handler. */
1312
+ Py_ssize_t
1313
+ _Py_write_noraise (int fd , const void * buf , size_t count )
1314
+ {
1315
+ return _Py_write_impl (fd , buf , count , 0 );
1316
+ }
1317
+
1283
1318
#ifdef HAVE_READLINK
1284
1319
1285
1320
/* Read value of symbolic link. Encode the path to the locale encoding, decode
0 commit comments