summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pym/portage/__init__.py26
-rw-r--r--pym/portage/exception.py4
-rw-r--r--pym/portage/locks.py13
3 files changed, 32 insertions, 11 deletions
diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py
index 9859e0f5e..6aa4d2664 100644
--- a/pym/portage/__init__.py
+++ b/pym/portage/__init__.py
@@ -3512,15 +3512,27 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",
from textwrap import wrap
waiting_msg = "\n".join(msg_prefix + line \
for line in wrap(waiting_msg, 65))
+
if locks_in_subdir:
- file_lock = portage.locks.lockfile(
- os.path.join(mysettings["DISTDIR"],
- locks_in_subdir, myfile), wantnewlockfile=1,
- waiting_msg=waiting_msg)
+ lock_file = os.path.join(mysettings["DISTDIR"],
+ locks_in_subdir, myfile)
+ else:
+ lock_file = myfile_path
+
+ lock_kwargs = {}
+ if fetchonly:
+ lock_kwargs["flags"] = os.O_NONBLOCK
else:
- file_lock = portage.locks.lockfile(
- myfile_path, wantnewlockfile=1,
- waiting_msg=waiting_msg)
+ lock_kwargs["waiting_msg"] = waiting_msg
+
+ try:
+ file_lock = portage.locks.lockfile(myfile_path,
+ wantnewlockfile=1, **lock_kwargs)
+ except portage.exception.TryAgain:
+ writemsg((">>> File '%s' is already locked by " + \
+ "another fetcher. Continuing...\n") % myfile,
+ noiselevel=-1)
+ continue
try:
if not listonly:
diff --git a/pym/portage/exception.py b/pym/portage/exception.py
index d91584b73..66cd16244 100644
--- a/pym/portage/exception.py
+++ b/pym/portage/exception.py
@@ -57,6 +57,10 @@ class PermissionDenied(PortageException):
from errno import EACCES as errno
"""Permission denied"""
+class TryAgain(PortageException):
+ from errno import EAGAIN as errno
+ """Try again"""
+
class ReadOnlyFileSystem(PortageException):
"""Read-only file system"""
diff --git a/pym/portage/locks.py b/pym/portage/locks.py
index 004108eb7..000cd3495 100644
--- a/pym/portage/locks.py
+++ b/pym/portage/locks.py
@@ -5,7 +5,8 @@
import errno, os, stat, time, types
-from portage.exception import InvalidData, DirectoryNotFound, FileNotFound
+from portage.exception import DirectoryNotFound, FileNotFound, \
+ InvalidData, TryAgain
from portage.data import portage_gid
from portage.util import writemsg
from portage.localization import _
@@ -17,7 +18,8 @@ def lockdir(mydir):
def unlockdir(mylock):
return unlockfile(mylock)
-def lockfile(mypath, wantnewlockfile=0, unlinkfile=0, waiting_msg=None):
+def lockfile(mypath, wantnewlockfile=0, unlinkfile=0,
+ waiting_msg=None, flags=0):
"""Creates all dirs upto, the given dir. Creates a lockfile
for the given directory as the file: directoryname+'.portage_lockfile'."""
import fcntl
@@ -54,7 +56,8 @@ def lockfile(mypath, wantnewlockfile=0, unlinkfile=0, waiting_msg=None):
except OSError, e:
if e[0] == 2: # No such file or directory
return lockfile(mypath, wantnewlockfile=wantnewlockfile,
- unlinkfile=unlinkfile, waiting_msg=waiting_msg)
+ unlinkfile=unlinkfile, waiting_msg=waiting_msg,
+ flags=flags)
else:
writemsg("Cannot chown a lockfile. This could cause inconvenience later.\n");
os.umask(old_mask)
@@ -78,6 +81,8 @@ def lockfile(mypath, wantnewlockfile=0, unlinkfile=0, waiting_msg=None):
raise
if e.errno in (errno.EACCES, errno.EAGAIN):
# resource temp unavailable; eg, someone beat us to the lock.
+ if flags & os.O_NONBLOCK:
+ raise TryAgain(mypath)
if waiting_msg is None:
if isinstance(mypath, int):
print "waiting for lock on fd %i" % myfd
@@ -114,7 +119,7 @@ def lockfile(mypath, wantnewlockfile=0, unlinkfile=0, waiting_msg=None):
writemsg("lockfile recurse\n",1)
lockfilename, myfd, unlinkfile, locking_method = lockfile(
mypath, wantnewlockfile=wantnewlockfile, unlinkfile=unlinkfile,
- waiting_msg=waiting_msg)
+ waiting_msg=waiting_msg, flags=flags)
writemsg(str((lockfilename,myfd,unlinkfile))+"\n",1)
return (lockfilename,myfd,unlinkfile,locking_method)