Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Adds a new sage-flock command based on the original pip2-lock command…
Browse files Browse the repository at this point in the history
…, but generalized to

running any command.

This is like a simplified version of the flock command on some systems, but I don't know how portable
that is (granted, flock(2) isn't necessarily all that portable either).

This removes the pip2-lock and pip3-lock commands and replaces their usage with the general sage-flock
command.
  • Loading branch information
embray committed Jul 10, 2017
1 parent c522ced commit 63f4b2d
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 116 deletions.
6 changes: 3 additions & 3 deletions build/bin/sage-pip-install
Expand Up @@ -60,10 +60,11 @@ fi
# We should avoid running pip2/3 while uninstalling a package because that
# is prone to race conditions. Therefore, we use a lockfile while
# running pip. This is implemented in the Python script pip2/3-lock.
LOCK="$SAGE_LOCAL/var/lock/$PIP.lock"

# Keep uninstalling as long as it succeeds
while true; do
out=$($PIP-lock uninstall --disable-pip-version-check -y "$name" 2>&1)
out=$(sage-flock -x $LOCK $PIP uninstall --disable-pip-version-check -y "$name" 2>&1)
if [ $? -ne 0 ]; then
break
fi
Expand All @@ -83,9 +84,8 @@ fi
# to apply a shared lock)
echo "Installing package $name using $PIP"

$PIP-lock SHARED install $pip_install_flags .
sage-flock -s $LOCK $PIP install $pip_install_flags .
if [ $? -ne 0 ]; then
echo >&2 "Error: installing with $PIP failed"
exit 3
fi

3 changes: 2 additions & 1 deletion build/bin/sage-spkg
Expand Up @@ -753,7 +753,8 @@ if [ "$UNAME" = "CYGWIN" ]; then
# Rebase after installing each package--in case any packages load this
# package at build time we need to ensure during the build that no binaries
# have conflicting address spaces
sage-rebase.sh "$SAGE_LOCAL" 2>/dev/null
sage-flock -x "$SAGE_LOCAL/var/lock/rebase.lock" \
sage-rebase.sh "$SAGE_LOCAL" 2>/dev/null
fi

echo "Successfully installed $PKG_NAME"
Expand Down
56 changes: 0 additions & 56 deletions src/bin/pip2-lock

This file was deleted.

56 changes: 0 additions & 56 deletions src/bin/pip3-lock

This file was deleted.

73 changes: 73 additions & 0 deletions src/bin/sage-flock
@@ -0,0 +1,73 @@
#!/usr/bin/env sage-python23
# vim: set filetype=python:
"""
This script runs the given command under a file lock (similar to the flock
command on some systems).
The command may also be a Python module in which case it is run in the same
Python interpreter as this script (a small optimization to avoid restarting the
Python interpreter).
"""

# This is originally motivated by pip, but has since been generalized. We
# should avoid running pip while uninstalling a package because that is prone
# to race conditions. This script runs pip under a lock. For details, see
# https://trac.sagemath.org/ticket/21672

from __future__ import print_function


import argparse
import fcntl
import os
import pipes
import sys


def main(argv=None):
parser = argparse.ArgumentParser(description=__doc__)
group = parser.add_mutually_exclusive_group()
group.add_argument('-s', '--shared', action='store_true',
help='create a shared lock')

# Note: A exclusive lock is created by default if no other flags are given,
# but supplying the --exclusive flag explicitly may help clarity
group.add_argument('-x', '--exclusive', action='store_true',
help='create an exclusive lock (the default)')
parser.add_argument('lock', metavar='LOCK', type=argparse.FileType('w+'),
help='filename of the lock')
parser.add_argument('command', metavar='COMMAND', nargs=argparse.REMAINDER,
help='command to run with the lock including any '
'arguments to that command')

args = parser.parse_args(argv)

if args.shared:
locktype = fcntl.LOCK_SH
else:
locktype = fcntl.LOCK_EX

lock = args.lock
command = args.command

# First try a non-blocking lock such that we can give an informative
# message while the user is waiting.
try:
fcntl.flock(lock, locktype | fcntl.LOCK_NB)
except IOError:
if locktype == fcntl.LOCK_SH:
kind = "shared"
else:
kind = "exclusive"

print("Waiting for {0} lock to run {1} ... ".format(
kind, ' '.join(pipes.quote(arg) for arg in command)), end='',
file=sys.stderr)
fcntl.flock(lock, locktype)
print("ok", file=sys.stderr)

os.execvp(command[0], command)


if __name__ == '__main__':
sys.exit(main())

0 comments on commit 63f4b2d

Please sign in to comment.