Skip to content

Commit 547e6f0

Browse files
committed
Replaced lock file code with flock()
1 parent 48c149c commit 547e6f0

File tree

1 file changed

+26
-21
lines changed

1 file changed

+26
-21
lines changed

git/util.py

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# This module is part of GitPython and is released under
55
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
66

7+
from fcntl import flock, LOCK_UN, LOCK_EX, LOCK_NB
78
import os
89
import re
910
import sys
@@ -324,12 +325,12 @@ def update(self, op_code, cur_count, max_count=None, message=''):
324325
325326
You may read the contents of the current line in self._cur_line"""
326327
pass
327-
328+
328329

329330
class CallableRemoteProgress(RemoteProgress):
330331
"""An implementation forwarding updates to any callable"""
331332
__slots__ = ('_callable')
332-
333+
333334
def __init__(self, fn):
334335
self._callable = fn
335336
super(CallableRemoteProgress, self).__init__()
@@ -535,9 +536,10 @@ class LockFile(object):
535536
As we are a utility class to be derived from, we only use protected methods.
536537
537538
Locks will automatically be released on destruction"""
538-
__slots__ = ("_file_path", "_owns_lock")
539+
__slots__ = ("_file_path", "_owns_lock", "_file_descriptor")
539540

540541
def __init__(self, file_path):
542+
self._file_descriptor = None
541543
self._file_path = file_path
542544
self._owns_lock = False
543545

@@ -559,17 +561,24 @@ def _obtain_lock_or_raise(self):
559561
:raise IOError: if a lock was already present or a lock file could not be written"""
560562
if self._has_lock():
561563
return
564+
562565
lock_file = self._lock_file_path()
563-
if os.path.isfile(lock_file):
564-
raise IOError("Lock for file %r did already exist, delete %r in case the lock is illegal" %
565-
(self._file_path, lock_file))
566+
567+
# Create lock file
568+
try:
569+
open(lock_file, 'a').close()
570+
except OSError as e:
571+
# Silence error only if file exists
572+
if e.errno != 17: # 17 -> File exists
573+
raise
566574

567575
try:
568-
fd = os.open(lock_file, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0)
569-
os.close(fd)
576+
fd = os.open(lock_file, os.O_WRONLY, 0)
577+
flock(fd, LOCK_EX | LOCK_NB)
570578
except OSError as e:
571579
raise IOError(str(e))
572580

581+
self._file_descriptor = fd
573582
self._owns_lock = True
574583

575584
def _obtain_lock(self):
@@ -582,19 +591,15 @@ def _release_lock(self):
582591
if not self._has_lock():
583592
return
584593

585-
# if someone removed our file beforhand, lets just flag this issue
586-
# instead of failing, to make it more usable.
587-
lfp = self._lock_file_path()
588-
try:
589-
# on bloody windows, the file needs write permissions to be removable.
590-
# Why ...
591-
if os.name == 'nt':
592-
os.chmod(lfp, 0o777)
593-
# END handle win32
594-
os.remove(lfp)
595-
except OSError:
596-
pass
594+
fd = self._file_descriptor
595+
lock_file = self._lock_file_path()
596+
597+
flock(fd, LOCK_UN)
598+
os.close(fd)
599+
os.remove(lock_file)
600+
597601
self._owns_lock = False
602+
self._file_descriptor = None
598603

599604

600605
class BlockingLockFile(LockFile):
@@ -629,7 +634,7 @@ def _obtain_lock(self):
629634
try:
630635
super(BlockingLockFile, self)._obtain_lock()
631636
except IOError:
632-
# synity check: if the directory leading to the lockfile is not
637+
# sanity check: if the directory leading to the lockfile is not
633638
# readable anymore, raise an execption
634639
curtime = time.time()
635640
if not os.path.isdir(os.path.dirname(self._lock_file_path())):

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy