From 7f91cb0ff4a14f572be84335e0ab2ff0db6febbb Mon Sep 17 00:00:00 2001 From: Steven ONeill Date: Thu, 2 Aug 2018 12:40:47 -0400 Subject: [PATCH] workaround to make chdir threadsafe until an alternative is found Signed-off-by: Steven ONeill --- lib/mixlib/archive/lib_archive.rb | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/lib/mixlib/archive/lib_archive.rb b/lib/mixlib/archive/lib_archive.rb index bef1a66..c7d86be 100644 --- a/lib/mixlib/archive/lib_archive.rb +++ b/lib/mixlib/archive/lib_archive.rb @@ -6,6 +6,12 @@ class LibArchive attr_reader :options attr_reader :archive + class << self + attr_accessor :mutex_chdir + end + + Mixlib::Archive::LibArchive.mutex_chdir = Mutex.new + def initialize(archive, options = {}) @archive = archive @options = options @@ -20,18 +26,24 @@ def extract(destination, perms: true, ignore: []) ignore_re = Regexp.union(ignore) flags = perms ? ::Archive::EXTRACT_PERM : nil FileUtils.mkdir_p(destination) - Dir.chdir(destination) do - reader = ::Archive::Reader.open_filename(@archive) - reader.each_entry do |entry| - if entry.pathname =~ ignore_re - Mixlib::Archive::Log.warn "ignoring entry #{entry.pathname}" - next - end + # @note Dir.chdir is applied to the process, thus it is not thread-safe + # and must be synchronized. + # TODO: figure out a better alternative to chdir + Mixlib::Archive::LibArchive.mutex_chdir.synchronize do + Dir.chdir(destination) do + reader = ::Archive::Reader.open_filename(@archive) - reader.extract(entry, flags.to_i) + reader.each_entry do |entry| + if entry.pathname =~ ignore_re + Mixlib::Archive::Log.warn "ignoring entry #{entry.pathname}" + next + end + + reader.extract(entry, flags.to_i) + end + reader.close end - reader.close end end