Skip to content

Commit

Permalink
Introduce safe_ensure_dirs as a safe os.makedirs replacement.
Browse files Browse the repository at this point in the history
It only uses os.makedirs call, which is more atomic than calling 2 procs. Thus exception due to already existent directory should not longer occur.
  • Loading branch information
abergmeier committed Dec 1, 2013
1 parent c2077a7 commit 0f5135e
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 19 deletions.
15 changes: 3 additions & 12 deletions tools/cache.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os.path, sys, shutil, hashlib, cPickle, zlib, time

import tempfiles
import shared

# Permanent cache for dlmalloc and stdlibc++
class Cache:
Expand All @@ -13,13 +14,7 @@ def __init__(self, dirname=None, debug=False):
self.debug = debug

def ensure(self):
try:
# Use makedirs here, so creating the path is as atomic as possible
os.makedirs(self.dirname)
except os.error, e:
# Ignore error for already existing dirname
if not os.path.exists(self.dirname):
raise e
shared.safe_ensure_dirs(self.dirname)

def erase(self):
tempfiles.try_delete(self.dirname)
Expand Down Expand Up @@ -53,11 +48,7 @@ def __init__(self, cache):

def ensure(self):
self.cache.ensure()
if not os.path.exists(self.dirname):
try:
os.makedirs(self.dirname)
except (IOError, OSError):
pass
shared.safe_ensure_dirs(self.dirname)

def get_shortkey(self, keys):
if type(keys) not in [list, tuple]:
Expand Down
24 changes: 17 additions & 7 deletions tools/shared.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import shutil, time, os, sys, json, tempfile, copy, shlex, atexit, subprocess, hashlib, cPickle, re
import shutil, time, os, sys, json, tempfile, copy, shlex, atexit, subprocess, hashlib, cPickle, re, errno
from subprocess import Popen, PIPE, STDOUT
from tempfile import mkstemp
from distutils.spawn import find_executable
Expand Down Expand Up @@ -480,8 +480,7 @@ def __init__(self, environ=os.environ):
if self.DEBUG:
try:
self.EMSCRIPTEN_TEMP_DIR = self.CANONICAL_TEMP_DIR
if not os.path.exists(self.EMSCRIPTEN_TEMP_DIR):
os.makedirs(self.EMSCRIPTEN_TEMP_DIR)
safe_ensure_dirs(self.EMSCRIPTEN_TEMP_DIR)
except Exception, e:
logging.debug(e + 'Could not create canonical temp dir. Check definition of TEMP_DIR in ~/.emscripten')

Expand Down Expand Up @@ -1017,8 +1016,7 @@ def link(files, target, force_archive_contents=False):
try:
temp_dir = os.path.join(EMSCRIPTEN_TEMP_DIR, 'ar_output_' + str(os.getpid()) + '_' + str(len(temp_dirs)))
temp_dirs.append(temp_dir)
if not os.path.exists(temp_dir):
os.makedirs(temp_dir)
safe_ensure_dirs(temp_dir)
os.chdir(temp_dir)
contents = filter(lambda x: len(x) > 0, Popen([LLVM_AR, 't', f], stdout=PIPE).communicate()[0].split('\n'))
#print >> sys.stderr, ' considering archive', f, ':', contents
Expand All @@ -1027,8 +1025,8 @@ def link(files, target, force_archive_contents=False):
else:
for content in contents: # ar will silently fail if the directory for the file does not exist, so make all the necessary directories
dirname = os.path.dirname(content)
if dirname and not os.path.exists(dirname):
os.makedirs(dirname)
if dirname:
safe_ensure_dirs(dirname)
Popen([LLVM_AR, 'xo', f], stdout=PIPE).communicate() # if absolute paths, files will appear there. otherwise, in this directory
contents = map(lambda content: os.path.join(temp_dir, content), contents)
contents = filter(os.path.exists, map(os.path.abspath, contents))
Expand Down Expand Up @@ -1637,5 +1635,17 @@ def unsuffixed(name):
def unsuffixed_basename(name):
return os.path.basename(unsuffixed(name))

def safe_ensure_dirs(dirname):
try:
os.makedirs(dirname)
except os.error, e:
# Ignore error for already existing dirname
if e.errno != errno.EEXIST:
raise e
# FIXME: Notice that this will result in a false positive,
# should the dirname be a file! There seems to no way to
# handle this atomically in Python 2.x.
# There is an additional option for Python 3.x, though.

import js_optimizer

0 comments on commit 0f5135e

Please sign in to comment.