summaryrefslogtreecommitdiff
path: root/lib/gitlab
diff options
context:
space:
mode:
authorAlexis Reigel <mail@koffeinfrei.org>2017-08-10 20:33:24 +0200
committerAlexis Reigel <mail@koffeinfrei.org>2017-08-14 12:57:56 +0200
commitedcc488b75d8c6fcad3994bcda30a82756496969 (patch)
tree18bda21e98f3cbfcad6b4007873f9ac3934a4a87 /lib/gitlab
parent6cd9888f6fc8bb1e0b6ff11ace8aacb19aedb268 (diff)
downloadgitlab-ce-edcc488b75d8c6fcad3994bcda30a82756496969.tar.gz
use mutex for keychain interaction
setting of the gpg home directory is not thread safe, as the directoy gets stored on the class. if multiple threads change the directory at the same time, one of the threads will be working in the wrong directory.
Diffstat (limited to 'lib/gitlab')
-rw-r--r--lib/gitlab/gpg.rb34
1 files changed, 26 insertions, 8 deletions
diff --git a/lib/gitlab/gpg.rb b/lib/gitlab/gpg.rb
index 653c56d925b..78ebd8866a1 100644
--- a/lib/gitlab/gpg.rb
+++ b/lib/gitlab/gpg.rb
@@ -2,6 +2,8 @@ module Gitlab
module Gpg
extend self
+ MUTEX = Mutex.new
+
module CurrentKeyChain
extend self
@@ -42,7 +44,30 @@ module Gitlab
end
end
- def using_tmp_keychain
+ # Allows thread safe switching of temporary keychain files
+ #
+ # 1. The current thread may use nesting of temporary keychain
+ # 2. Another thread needs to wait for the lock to be released
+ def using_tmp_keychain(&block)
+ if MUTEX.locked? && MUTEX.owned?
+ optimistic_using_tmp_keychain(&block)
+ else
+ MUTEX.synchronize do
+ optimistic_using_tmp_keychain(&block)
+ end
+ end
+ end
+
+ # 1. Returns the custom home directory if one has been set by calling
+ # `GPGME::Engine.home_dir=`
+ # 2. Returns the default home directory otherwise
+ def current_home_dir
+ GPGME::Engine.info.first.home_dir || GPGME::Engine.dirinfo('homedir')
+ end
+
+ private
+
+ def optimistic_using_tmp_keychain
Dir.mktmpdir do |dir|
previous_dir = current_home_dir
@@ -55,12 +80,5 @@ module Gitlab
return_value
end
end
-
- # 1. Returns the custom home directory if one has been set by calling
- # `GPGME::Engine.home_dir=`
- # 2. Returns the default home directory otherwise
- def current_home_dir
- GPGME::Engine.info.first.home_dir || GPGME::Engine.dirinfo('homedir')
- end
end
end