Project

General

Profile

Feature #5976 ยป patch.diff

Glass_saga (Masaki Matsushita), 02/07/2012 12:00 PM

View differences:

lib/pstore.rb
@filename = file
@abort = false
@ultra_safe = false
@modified = false
@thread_safe = thread_safe
@lock = Mutex.new
end
......
def in_transaction_wr
in_transaction
raise PStore::Error, "in read-only transaction" if @rdonly
@modified = true
end
private :in_transaction, :in_transaction_wr
......
@lock.synchronize do
@rdonly = read_only
@abort = false
@modified = false
file = open_and_lock_file(@filename, read_only)
if file
begin
@table, checksum, original_data_size = load_data(file, read_only)
@table = load_data(file)
catch(:pstore_abort_transaction) do
value = yield(self)
end
if !@abort && !read_only
save_data(checksum, original_data_size, file)
save_data(file)
end
ensure
file.close if !file.closed?
......
end
private
# Constant for relieving Ruby's garbage collector.
# Constants for compatibility.
EMPTY_STRING = ""
EMPTY_MARSHAL_DATA = Marshal.dump({})
EMPTY_MARSHAL_CHECKSUM = Digest::MD5.digest(EMPTY_MARSHAL_DATA)
......
end
# Load the given PStore file.
# If +read_only+ is true, the unmarshalled Hash will be returned.
# If +read_only+ is false, a 3-tuple will be returned: the unmarshalled
# Hash, an MD5 checksum of the data, and the size of the data.
def load_data(file, read_only)
if read_only
begin
table = load(file)
raise Error, "PStore file seems to be corrupted." unless table.is_a?(Hash)
rescue EOFError
# This seems to be a newly-created file.
table = {}
end
table
else
data = file.read
if data.empty?
# This seems to be a newly-created file.
table = {}
checksum = empty_marshal_checksum
size = empty_marshal_data.bytesize
else
table = load(data)
checksum = Digest::MD5.digest(data)
size = data.bytesize
raise Error, "PStore file seems to be corrupted." unless table.is_a?(Hash)
end
data.replace(EMPTY_STRING)
[table, checksum, size]
# The unmarshalled Hash will be returned.
def load_data(file)
begin
table = load(file)
raise Error, "PStore file seems to be corrupted." unless table.is_a?(Hash)
rescue EOFError
# This seems to be a newly-created file.
table = {}
end
table
end
def on_windows?
......
is_windows
end
def save_data(original_checksum, original_file_size, file)
def save_data(file)
new_data = dump(@table)
if new_data.bytesize != original_file_size || Digest::MD5.digest(new_data) != original_checksum
if @modified
if @ultra_safe && !on_windows?
# Windows doesn't support atomic file renames.
save_data_with_atomic_file_rename_strategy(new_data, file)
......
end
end
new_data.replace(EMPTY_STRING)
new_data.clear
end
def save_data_with_atomic_file_rename_strategy(data, file)
    (1-1/1)