summaryrefslogtreecommitdiffstats
path: root/lib/puppet/util
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-12-10 21:36:39 -0600
committerJames Turnbull <james@lovedthanlost.net>2008-12-12 09:44:42 +1100
commit2385a78a7c455affed26955142a4d4d3ce53c37f (patch)
tree1cf8df7b6812309371e25ddc0287df086e3afc4a /lib/puppet/util
parent2961b832de8d0bd6f73dfb6a65a424fd6eb7746a (diff)
downloadpuppet-2385a78a7c455affed26955142a4d4d3ce53c37f.tar.gz
puppet-2385a78a7c455affed26955142a4d4d3ce53c37f.tar.xz
puppet-2385a78a7c455affed26955142a4d4d3ce53c37f.zip
Preparing to fix #1812 - Moving locking code to a module
This moves the locking code out of Puppet::Util into a separate module, to make the code cleaner. Signed-off-by: Luke Kanies <luke@madstop.com>
Diffstat (limited to 'lib/puppet/util')
-rw-r--r--lib/puppet/util/file_locking.rb47
-rw-r--r--lib/puppet/util/storage.rb6
2 files changed, 51 insertions, 2 deletions
diff --git a/lib/puppet/util/file_locking.rb b/lib/puppet/util/file_locking.rb
new file mode 100644
index 000000000..80a0b2b0c
--- /dev/null
+++ b/lib/puppet/util/file_locking.rb
@@ -0,0 +1,47 @@
+require 'puppet/util'
+
+module Puppet::Util::FileLocking
+ module_function
+
+ # Create a shared lock for reading
+ def readlock(file)
+ Puppet::Util.sync(file).synchronize(Sync::SH) do
+ File.open(file) { |f|
+ f.lock_shared { |lf| yield lf }
+ }
+ end
+ end
+
+ # Create an exclusive lock for writing, and do the writing in a
+ # tmp file.
+ def writelock(file, mode = nil)
+ unless FileTest.directory?(File.dirname(file))
+ raise Puppet::DevError, "Cannot create %s; directory %s does not exist" % [file, File.dirname(file)]
+ end
+ tmpfile = file + ".tmp"
+
+ unless mode
+ begin
+ mode = File.stat(file).mode
+ rescue
+ mode = 0600
+ end
+ end
+
+ Puppet::Util.sync(file).synchronize(Sync::EX) do
+ File.open(file, "w", mode) do |rf|
+ rf.lock_exclusive do |lrf|
+ File.open(tmpfile, "w", mode) do |tf|
+ yield tf
+ end
+ begin
+ File.rename(tmpfile, file)
+ rescue => detail
+ File.unlink(tmpfile) if File.exist?(tmpfile)
+ raise Puppet::Error, "Could not rename %s to %s: %s; file %s was unchanged" % [file, tmpfile, Thread.current.object_id, detail, file]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/puppet/util/storage.rb b/lib/puppet/util/storage.rb
index dc4e9cd71..01c411181 100644
--- a/lib/puppet/util/storage.rb
+++ b/lib/puppet/util/storage.rb
@@ -1,6 +1,8 @@
require 'yaml'
require 'sync'
+require 'puppet/util/file_locking'
+
# a class for storing state
class Puppet::Util::Storage
include Singleton
@@ -59,7 +61,7 @@ class Puppet::Util::Storage
return
end
Puppet::Util.benchmark(:debug, "Loaded state") do
- Puppet::Util.readlock(Puppet[:statefile]) do |file|
+ Puppet::Util::FileLocking.readlock(Puppet[:statefile]) do |file|
begin
@@state = YAML.load(file)
rescue => detail
@@ -97,7 +99,7 @@ class Puppet::Util::Storage
end
Puppet::Util.benchmark(:debug, "Stored state") do
- Puppet::Util.writelock(Puppet[:statefile], 0660) do |file|
+ Puppet::Util::FileLocking.writelock(Puppet[:statefile], 0660) do |file|
file.print YAML.dump(@@state)
end
end