Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1b3fedd

Browse files
committed
LockFile: id representing the instance that keeps the lock is unique now - locks will check whether the lock they wrote truly is theirs - in case threads are racing, this might not be the case. Now this issue will be detected and results in a proper failure
1 parentdcf2c3b commit1b3fedd

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

‎lib/git/utils.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ def _lock_file_path(self):
119119
"""
120120
return"%s.lock"% (self._file_path)
121121

122+
def_get_id(self):
123+
"""Returns string id to be written into the lock file"""
124+
return"%i|%i"% (os.getpid(),hash(self))
125+
122126
def_has_lock(self):
123127
"""
124128
Return
@@ -133,13 +137,13 @@ def _has_lock(self):
133137
lock_file=self._lock_file_path()
134138
try:
135139
fp=open(lock_file,"rb")
136-
pid=int(fp.read())
140+
pid=fp.read()
137141
fp.close()
138142
exceptIOError:
139143
raiseAssertionError("The lock file at %s could not be read"%lock_file)
140144

141-
ifpid!=os.getpid():
142-
raiseAssertionError("We claim to own the lock at %s, but it was not owned by our process %i, but by %i"% (lock_file,os.getpid(),pid))
145+
ifpid!=self._get_id():
146+
raiseAssertionError("We claim to own the lock at %s, but it was not owned by our process %r, but by %r"% (lock_file,self._get_id(),pid))
143147

144148
returnTrue
145149

@@ -152,14 +156,25 @@ def _obtain_lock_or_raise(self):
152156
"""
153157
ifself._has_lock():
154158
return
155-
156159
lock_file=self._lock_file_path()
157-
ifos.path.exists(lock_file):
160+
ifos.path.isfile(lock_file):
158161
raiseIOError("Lock for file %r did already exist, delete %r in case the lock is illegal"% (self._file_path,lock_file))
159-
162+
163+
my_id=self._get_id()
160164
fp=open(lock_file,"wb")
161-
fp.write(str(os.getpid()))
165+
fp.write(my_id)
166+
fp.close()
167+
168+
# verify its truly us who got the lock - if two threads are doing this within the
169+
# fraction of a millisecond, it is possible to actually trick the FS
170+
# and two threads write, but only one succeeds.
171+
fp=open(lock_file,'rb')
172+
actual_id=fp.read()
162173
fp.close()
174+
ifactual_id!=my_id:
175+
msg="Failed to obtain lock for file %r as the process identified by %r outraced this process or thread %r"% (self._file_path,actual_id,my_id)
176+
raiseIOError(msg)
177+
# END verification
163178

164179
self._owns_lock=True
165180

@@ -175,11 +190,11 @@ def _release_lock(self):
175190
Release our lock if we have one
176191
"""
177192
ifnotself._has_lock():
178-
return
179-
193+
return
180194
os.remove(self._lock_file_path())
181195
self._owns_lock=False
182196

197+
183198
classBlockingLockFile(LockFile):
184199
"""The lock file will block until a lock could be obtained, or fail after
185200
a specified timeout"""
@@ -206,7 +221,7 @@ def _obtain_lock(self):
206221
maxtime=starttime+float(self._max_block_time)
207222
whileTrue:
208223
try:
209-
self._obtain_lock_or_raise()
224+
super(BlockingLockFile,self)._obtain_lock()
210225
exceptIOError:
211226
curtime=time.time()
212227
ifcurtime>=maxtime:
@@ -219,7 +234,6 @@ def _obtain_lock(self):
219234
# END endless loop
220235

221236

222-
223237
classConcurrentWriteOperation(LockFile):
224238
"""
225239
This class facilitates a safe write operation to a file on disk such that we:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp