##// END OF EJS Templates
Backport PR #4748: fix race condition in profiledir creation.
MinRK -
Show More
@@ -24,6 +24,7 Authors:
24 import os
24 import os
25 import shutil
25 import shutil
26 import errno
26 import errno
27 import time
27
28
28 from IPython.config.configurable import LoggingConfigurable
29 from IPython.config.configurable import LoggingConfigurable
29 from IPython.utils.path import get_ipython_package_dir, expand_path
30 from IPython.utils.path import get_ipython_package_dir, expand_path
@@ -76,9 +77,17 class ProfileDir(LoggingConfigurable):
76 if self._location_isset:
77 if self._location_isset:
77 raise RuntimeError("Cannot set profile location more than once.")
78 raise RuntimeError("Cannot set profile location more than once.")
78 self._location_isset = True
79 self._location_isset = True
79 if not os.path.isdir(new):
80 num_tries = 0
80 os.makedirs(new)
81 max_tries = 5
81
82 while not os.path.isdir(new):
83 try:
84 os.makedirs(new)
85 except OSError:
86 if num_tries > max_tries:
87 raise
88 num_tries += 1
89 time.sleep(0.5)
90
82 # ensure config files exist:
91 # ensure config files exist:
83 self.security_dir = os.path.join(new, self.security_dir_name)
92 self.security_dir = os.path.join(new, self.security_dir_name)
84 self.log_dir = os.path.join(new, self.log_dir_name)
93 self.log_dir = os.path.join(new, self.log_dir_name)
@@ -88,12 +97,12 class ProfileDir(LoggingConfigurable):
88
97
89 def _log_dir_changed(self, name, old, new):
98 def _log_dir_changed(self, name, old, new):
90 self.check_log_dir()
99 self.check_log_dir()
91
100
92 def _mkdir(self, path, mode=None):
101 def _mkdir(self, path, mode=None):
93 """ensure a directory exists at a given path
102 """ensure a directory exists at a given path
94
103
95 This is a version of os.mkdir, with the following differences:
104 This is a version of os.mkdir, with the following differences:
96
105
97 - returns True if it created the directory, False otherwise
106 - returns True if it created the directory, False otherwise
98 - ignores EEXIST, protecting against race conditions where
107 - ignores EEXIST, protecting against race conditions where
99 the dir may have been created in between the check and
108 the dir may have been created in between the check and
@@ -120,7 +129,7 class ProfileDir(LoggingConfigurable):
120 return False
129 return False
121 else:
130 else:
122 raise
131 raise
123
132
124 return True
133 return True
125
134
126 def check_log_dir(self):
135 def check_log_dir(self):
@@ -248,5 +257,3 class ProfileDir(LoggingConfigurable):
248 if not os.path.isdir(profile_dir):
257 if not os.path.isdir(profile_dir):
249 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
258 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
250 return cls(location=profile_dir, config=config)
259 return cls(location=profile_dir, config=config)
251
252
General Comments 0
You need to be logged in to leave comments. Login now