From c4b9a0df28e944c5972bcd56aee653bef0e1e683 Mon Sep 17 00:00:00 2001 From: Fabio Erculiani Date: Sat, 1 Sep 2012 15:18:11 +0200 Subject: [PATCH] [entropy.dump] do not use os.fdopen() in dumpobj() It has been observed that using os.fdopen() below in multi-threaded scenarios is causing EBADF (thus OSError). There is probably a racen condition down in the stack or mkstemp() itself is not guaranteed against concurrent access. For now, just consume one more file descriptor and avoid the race completely. --- lib/entropy/dump.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/entropy/dump.py b/lib/entropy/dump.py index 721fcd4f4..ed1dc0005 100644 --- a/lib/entropy/dump.py +++ b/lib/entropy/dump.py @@ -109,13 +109,17 @@ def dumpobj(name, my_object, complete_path = False, ignore_exceptions = True, dmp_name = os.path.basename(dmpfile) tmp_fd, tmp_dmpfile = tempfile.mkstemp( dir=c_dump_dir, prefix=dmp_name) - with os.fdopen(tmp_fd, "wb") as dmp_f: + # WARNING: it has been observed that using + # os.fdopen() below in multi-threaded scenarios + # is causing EBADF. There is probably a race + # condition down in the stack. + with open(tmp_dmpfile, "wb") as dmp_f: if const_is_python3(): pickle.dump(my_object, dmp_f, protocol = COMPAT_PICKLE_PROTOCOL, fix_imports = True) else: pickle.dump(my_object, dmp_f) - dmp_f.flush() + const_setup_file(tmp_dmpfile, E_GID, custom_permissions) os.rename(tmp_dmpfile, dmpfile)