From 7cfb8eaa937bf4da88c4c1709bd421f37a5f64f5 2013-12-30 06:28:45 From: James Porter Date: 2013-12-30 06:28:45 Subject: [PATCH] fix race condition in profiledir creation. --- diff --git a/IPython/core/profiledir.py b/IPython/core/profiledir.py index 2ebc5fe..7cae45b 100644 --- a/IPython/core/profiledir.py +++ b/IPython/core/profiledir.py @@ -24,6 +24,7 @@ Authors: import os import shutil import errno +import time from IPython.config.configurable import LoggingConfigurable from IPython.utils.path import get_ipython_package_dir, expand_path @@ -79,9 +80,17 @@ class ProfileDir(LoggingConfigurable): if self._location_isset: raise RuntimeError("Cannot set profile location more than once.") self._location_isset = True - if not os.path.isdir(new): - os.makedirs(new) - + num_tries = 0 + max_tries = 5 + while not os.path.isdir(new): + try: + os.makedirs(new) + except OSError: + if num_tries > max_tries: + raise + num_tries += 1 + time.sleep(0.5) + # ensure config files exist: self.security_dir = os.path.join(new, self.security_dir_name) self.log_dir = os.path.join(new, self.log_dir_name) @@ -92,12 +101,12 @@ class ProfileDir(LoggingConfigurable): def _log_dir_changed(self, name, old, new): self.check_log_dir() - + def _mkdir(self, path, mode=None): """ensure a directory exists at a given path - + This is a version of os.mkdir, with the following differences: - + - returns True if it created the directory, False otherwise - ignores EEXIST, protecting against race conditions where the dir may have been created in between the check and @@ -124,7 +133,7 @@ class ProfileDir(LoggingConfigurable): return False else: raise - + return True def check_log_dir(self): @@ -270,5 +279,3 @@ class ProfileDir(LoggingConfigurable): if not os.path.isdir(profile_dir): raise ProfileDirError('Profile directory not found: %s' % profile_dir) return cls(location=profile_dir, config=config) - -