Simplify lock context managers.
This commit is contained in:
parent
ccf311c9c6
commit
e17ad6a684
10 changed files with 49 additions and 43 deletions
|
@ -29,13 +29,15 @@
|
||||||
import time
|
import time
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
|
# Default timeout for locks.
|
||||||
|
DEFAULT_TIMEOUT = 60
|
||||||
|
|
||||||
|
class _ReadLockContext(object):
|
||||||
|
"""Context manager that takes and releases a read lock.
|
||||||
|
|
||||||
class Read_Lock_Instance(object):
|
|
||||||
"""
|
|
||||||
A context manager for getting shared access to the object lock
|
|
||||||
Arguments are lock and timeout (default 5 minutes)
|
Arguments are lock and timeout (default 5 minutes)
|
||||||
"""
|
"""
|
||||||
def __init__(self, lock, timeout=300):
|
def __init__(self, lock, timeout=DEFAULT_TIMEOUT):
|
||||||
self._lock = lock
|
self._lock = lock
|
||||||
self._timeout = timeout
|
self._timeout = timeout
|
||||||
|
|
||||||
|
@ -46,12 +48,12 @@ def __exit__(self,type,value,traceback):
|
||||||
self._lock.release_read()
|
self._lock.release_read()
|
||||||
|
|
||||||
|
|
||||||
class Write_Lock_Instance(object):
|
class _WriteLockContext(object):
|
||||||
"""
|
"""Context manager that takes and releases a write lock.
|
||||||
A context manager for getting exclusive access to the object lock
|
|
||||||
Arguments are lock and timeout (default 5 minutes)
|
Arguments are lock and timeout (default 5 minutes)
|
||||||
"""
|
"""
|
||||||
def __init__(self, lock, timeout=300):
|
def __init__(self, lock, timeout=DEFAULT_TIMEOUT):
|
||||||
self._lock = lock
|
self._lock = lock
|
||||||
self._timeout = timeout
|
self._timeout = timeout
|
||||||
|
|
||||||
|
@ -72,7 +74,17 @@ def __init__(self, file_path):
|
||||||
self._writes = 0
|
self._writes = 0
|
||||||
|
|
||||||
|
|
||||||
def acquire_read(self,timeout):
|
def write_lock(self, timeout=DEFAULT_TIMEOUT):
|
||||||
|
"""Convenience method that returns a write lock context."""
|
||||||
|
return _WriteLockContext(self, timeout)
|
||||||
|
|
||||||
|
|
||||||
|
def read_lock(self, timeout=DEFAULT_TIMEOUT):
|
||||||
|
"""Convenience method that returns a read lock context."""
|
||||||
|
return _ReadLockContext(self, timeout)
|
||||||
|
|
||||||
|
|
||||||
|
def acquire_read(self, timeout):
|
||||||
"""
|
"""
|
||||||
Implements recursive lock. If held in both read and write mode,
|
Implements recursive lock. If held in both read and write mode,
|
||||||
the write lock will be maintained until all locks are released
|
the write lock will be maintained until all locks are released
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
from llnl.util.lang import attr_setdefault
|
from llnl.util.lang import attr_setdefault
|
||||||
from llnl.util.lock import *
|
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
import spack.spec
|
import spack.spec
|
||||||
|
@ -125,7 +124,7 @@ def elide_list(line_list, max_num=10):
|
||||||
|
|
||||||
|
|
||||||
def disambiguate_spec(spec):
|
def disambiguate_spec(spec):
|
||||||
with Read_Lock_Instance(spack.installed_db.lock,1800):
|
with spack.installed_db.read_lock():
|
||||||
matching_specs = spack.installed_db.get_installed(spec)
|
matching_specs = spack.installed_db.get_installed(spec)
|
||||||
if not matching_specs:
|
if not matching_specs:
|
||||||
tty.die("Spec '%s' matches no installed packages." % spec)
|
tty.die("Spec '%s' matches no installed packages." % spec)
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
##############################################################################
|
##############################################################################
|
||||||
from external import argparse
|
from external import argparse
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
from llnl.util.lock import *
|
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
|
@ -55,7 +54,7 @@ def deactivate(parser, args):
|
||||||
if args.all:
|
if args.all:
|
||||||
if pkg.extendable:
|
if pkg.extendable:
|
||||||
tty.msg("Deactivating all extensions of %s" % pkg.spec.short_spec)
|
tty.msg("Deactivating all extensions of %s" % pkg.spec.short_spec)
|
||||||
with Read_Lock_Instance(spack.installed_db.lock,1800):
|
with spack.installed_db.read_lock():
|
||||||
ext_pkgs = spack.installed_db.installed_extensions_for(spec)
|
ext_pkgs = spack.installed_db.installed_extensions_for(spec)
|
||||||
|
|
||||||
for ext_pkg in ext_pkgs:
|
for ext_pkg in ext_pkgs:
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
from external import argparse
|
from external import argparse
|
||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
from llnl.util.lock import *
|
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
|
@ -55,7 +54,7 @@ def diy(self, args):
|
||||||
if not args.spec:
|
if not args.spec:
|
||||||
tty.die("spack diy requires a package spec argument.")
|
tty.die("spack diy requires a package spec argument.")
|
||||||
|
|
||||||
with Write_Lock_Instance(spack.installed_db.lock,1800):
|
with spack.installed_db.write_lock():
|
||||||
specs = spack.cmd.parse_specs(args.spec)
|
specs = spack.cmd.parse_specs(args.spec)
|
||||||
if len(specs) > 1:
|
if len(specs) > 1:
|
||||||
tty.die("spack diy only takes one spec.")
|
tty.die("spack diy only takes one spec.")
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
from llnl.util.tty.colify import colify
|
from llnl.util.tty.colify import colify
|
||||||
from llnl.util.lock import *
|
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
|
@ -81,7 +80,7 @@ def extensions(parser, args):
|
||||||
colify(ext.name for ext in extensions)
|
colify(ext.name for ext in extensions)
|
||||||
|
|
||||||
# List specs of installed extensions.
|
# List specs of installed extensions.
|
||||||
with Read_Lock_Instance(spack.installed_db.lock,1800):
|
with spack.installed_db.read_lock():
|
||||||
installed = [s.spec for s in spack.installed_db.installed_extensions_for(spec)]
|
installed = [s.spec for s in spack.installed_db.installed_extensions_for(spec)]
|
||||||
print
|
print
|
||||||
if not installed:
|
if not installed:
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
from llnl.util.tty.colify import *
|
from llnl.util.tty.colify import *
|
||||||
from llnl.util.tty.color import *
|
from llnl.util.tty.color import *
|
||||||
from llnl.util.lang import *
|
from llnl.util.lang import *
|
||||||
from llnl.util.lock import *
|
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
import spack.spec
|
import spack.spec
|
||||||
|
@ -139,11 +138,11 @@ def find(parser, args):
|
||||||
|
|
||||||
# Get all the specs the user asked for
|
# Get all the specs the user asked for
|
||||||
if not query_specs:
|
if not query_specs:
|
||||||
with Read_Lock_Instance(spack.installed_db.lock, 1800):
|
with spack.installed_db.read_lock():
|
||||||
specs = set(spack.installed_db.installed_package_specs())
|
specs = set(spack.installed_db.installed_package_specs())
|
||||||
|
|
||||||
else:
|
else:
|
||||||
with Read_Lock_Instance(spack.installed_db.lock, 1800):
|
with spack.installed_db.read_lock():
|
||||||
results = [set(spack.installed_db.get_installed(qs)) for qs in query_specs]
|
results = [set(spack.installed_db.get_installed(qs)) for qs in query_specs]
|
||||||
specs = set.union(*results)
|
specs = set.union(*results)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# Copyright (c) 2013, Lawrence Livermore National Security, LLC.
|
# Copyright (c) 2013-2015, Lawrence Livermore National Security, LLC.
|
||||||
# Produced at the Lawrence Livermore National Laboratory.
|
# Produced at the Lawrence Livermore National Laboratory.
|
||||||
#
|
#
|
||||||
# This file is part of Spack.
|
# This file is part of Spack.
|
||||||
|
@ -23,21 +23,10 @@
|
||||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
##############################################################################
|
##############################################################################
|
||||||
from external import argparse
|
from external import argparse
|
||||||
|
|
||||||
from llnl.util.lock import *
|
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
import os
|
|
||||||
|
|
||||||
description = "Correct database irregularities"
|
description = "Correct database irregularities"
|
||||||
|
|
||||||
#Very basic version of spack fsck
|
# Very basic version of spack fsck
|
||||||
def fsck(parser, args):
|
def fsck(parser, args):
|
||||||
with Write_Lock_Instance(spack.installed_db.lock,1800):
|
spack.installed_db.reindex(spack.install_layout)
|
||||||
#remove database file
|
|
||||||
if os.path.exists(spack.installed_db._file_path):
|
|
||||||
os.remove(spack.installed_db._file_path)
|
|
||||||
#read database
|
|
||||||
spack.installed_db.read_database()
|
|
||||||
#write database
|
|
||||||
spack.installed_db.write()
|
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
from external import argparse
|
from external import argparse
|
||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
from llnl.util.lock import *
|
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
|
@ -69,7 +68,7 @@ def install(parser, args):
|
||||||
if args.no_checksum:
|
if args.no_checksum:
|
||||||
spack.do_checksum = False # TODO: remove this global.
|
spack.do_checksum = False # TODO: remove this global.
|
||||||
|
|
||||||
with Write_Lock_Instance(spack.installed_db.lock,1800):
|
with spack.installed_db.write_lock():
|
||||||
specs = spack.cmd.parse_specs(args.packages, concretize=True)
|
specs = spack.cmd.parse_specs(args.packages, concretize=True)
|
||||||
for spec in specs:
|
for spec in specs:
|
||||||
package = spack.db.get(spec)
|
package = spack.db.get(spec)
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
from llnl.util.tty.colify import colify
|
from llnl.util.tty.colify import colify
|
||||||
from llnl.util.lock import *
|
|
||||||
|
|
||||||
import spack
|
import spack
|
||||||
import spack.cmd
|
import spack.cmd
|
||||||
|
@ -54,7 +53,7 @@ def uninstall(parser, args):
|
||||||
if not args.packages:
|
if not args.packages:
|
||||||
tty.die("uninstall requires at least one package argument.")
|
tty.die("uninstall requires at least one package argument.")
|
||||||
|
|
||||||
with Write_Lock_Instance(spack.installed_db.lock,1800):
|
with spack.installed_db.write_lock():
|
||||||
specs = spack.cmd.parse_specs(args.packages)
|
specs = spack.cmd.parse_specs(args.packages)
|
||||||
|
|
||||||
# For each spec provided, make sure it refers to only one package.
|
# For each spec provided, make sure it refers to only one package.
|
||||||
|
|
|
@ -24,13 +24,14 @@
|
||||||
##############################################################################
|
##############################################################################
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
import socket
|
||||||
|
|
||||||
from external import yaml
|
from external import yaml
|
||||||
from external.yaml.error import MarkedYAMLError, YAMLError
|
from external.yaml.error import MarkedYAMLError, YAMLError
|
||||||
|
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
from llnl.util.filesystem import *
|
from llnl.util.filesystem import *
|
||||||
from llnl.util.lock import *
|
from llnl.util.lock import Lock
|
||||||
|
|
||||||
import spack.spec
|
import spack.spec
|
||||||
from spack.version import Version
|
from spack.version import Version
|
||||||
|
@ -99,6 +100,16 @@ def __init__(self, root):
|
||||||
self._last_write_time = 0
|
self._last_write_time = 0
|
||||||
|
|
||||||
|
|
||||||
|
def write_lock(self):
|
||||||
|
"""Get a write lock context for use in a `with` block."""
|
||||||
|
return self.lock.write_lock()
|
||||||
|
|
||||||
|
|
||||||
|
def read_lock(self):
|
||||||
|
"""Get a read lock context for use in a `with` block."""
|
||||||
|
return self.lock.read_lock()
|
||||||
|
|
||||||
|
|
||||||
def _write_to_yaml(self, stream):
|
def _write_to_yaml(self, stream):
|
||||||
"""Write out the databsae to a YAML file."""
|
"""Write out the databsae to a YAML file."""
|
||||||
# map from per-spec hash code to installation record.
|
# map from per-spec hash code to installation record.
|
||||||
|
@ -198,13 +209,14 @@ def check(cond, msg):
|
||||||
|
|
||||||
def reindex(self, directory_layout):
|
def reindex(self, directory_layout):
|
||||||
"""Build database index from scratch based from a directory layout."""
|
"""Build database index from scratch based from a directory layout."""
|
||||||
with Write_Lock_Instance(self.lock, 60):
|
with self.write_lock():
|
||||||
data = {}
|
data = {}
|
||||||
for spec in directory_layout.all_specs():
|
for spec in directory_layout.all_specs():
|
||||||
path = directory_layout.path_for_spec(spec)
|
path = directory_layout.path_for_spec(spec)
|
||||||
hash_key = spec.dag_hash()
|
hash_key = spec.dag_hash()
|
||||||
data[hash_key] = InstallRecord(spec, path)
|
data[hash_key] = InstallRecord(spec, path)
|
||||||
self._data = data
|
self._data = data
|
||||||
|
|
||||||
self.write()
|
self.write()
|
||||||
|
|
||||||
|
|
||||||
|
@ -264,7 +276,7 @@ def add(self, spec, path):
|
||||||
Write the database back to memory
|
Write the database back to memory
|
||||||
"""
|
"""
|
||||||
# Should always already be locked
|
# Should always already be locked
|
||||||
with Write_Lock_Instance(self.lock, 60):
|
with self.write_lock():
|
||||||
self.read()
|
self.read()
|
||||||
self._data[spec.dag_hash()] = InstallRecord(spec, path)
|
self._data[spec.dag_hash()] = InstallRecord(spec, path)
|
||||||
self.write()
|
self.write()
|
||||||
|
@ -278,7 +290,7 @@ def remove(self, spec):
|
||||||
Writes the database back to memory
|
Writes the database back to memory
|
||||||
"""
|
"""
|
||||||
# Should always already be locked
|
# Should always already be locked
|
||||||
with Write_Lock_Instance(self.lock, 60):
|
with self.write_lock():
|
||||||
self.read()
|
self.read()
|
||||||
hash_key = spec.dag_hash()
|
hash_key = spec.dag_hash()
|
||||||
if hash_key in self._data:
|
if hash_key in self._data:
|
||||||
|
@ -314,7 +326,7 @@ def installed_package_specs(self):
|
||||||
and return their specs
|
and return their specs
|
||||||
"""
|
"""
|
||||||
# Should always already be locked
|
# Should always already be locked
|
||||||
with Read_Lock_Instance(self.lock, 60):
|
with self.read_lock():
|
||||||
self.read()
|
self.read()
|
||||||
return sorted(rec.spec for rec in self._data.values())
|
return sorted(rec.spec for rec in self._data.values())
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue