Merge branch 'master' into use-monotonic-monotonic

Conflicts:
	ChangeLog
This commit is contained in:
Joshua Harlow
2015-06-16 08:16:27 -07:00
8 changed files with 74 additions and 11 deletions

View File

@@ -1,8 +1,19 @@
0.11:
- Directly use monotonic.monotonic.
0.10:
- Add LICENSE in generated source tarballs
- Add a version.py file that can be used to
extract the current version.
0.9:
- Allow providing a non-standard (eventlet or
other condition class) to the r/w lock for
cases where it is useful to do so.
- Directly use monotonic.monotonic.
- Instead of having the r/w lock take a find
eventlet keyword argument, allow for it to
be provided a function that will be later
called to get the current thread. This allows
for the current *hack* to be easily removed
by users (if they so desire).
0.8:
- Add fastener logo (from openclipart).
- Ensure r/w writer -> reader -> writer

3
MANIFEST.in Normal file
View File

@@ -0,0 +1,3 @@
include LICENSE
include ChangeLog
include README.rst

View File

@@ -8,6 +8,10 @@ Fasteners
:target: https://readthedocs.org/projects/fasteners/?badge=latest
:alt: Documentation Status
.. image:: https://img.shields.io/pypi/dm/fasteners.svg
:target: https://pypi.python.org/pypi/fasteners/
:alt: Downloads
Overview
--------

View File

@@ -16,6 +16,8 @@ import sys
import os
import shlex
from fasteners import version as fasteners_version
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
@@ -59,10 +61,10 @@ author = u'Joshua Harlow, OpenStack Developers'
# built documents.
#
# The short X.Y version.
version = '0.8'
version = fasteners_version.version_string()
# The full version, including alpha/beta/rc tags.
release = '0.8'
release = fasteners_version.version_string()
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@@ -120,9 +120,7 @@ class ReaderWriterLock(object):
READER = 'r'
@staticmethod
def _fetch_current_thread_functor(find_eventlet=True):
if not find_eventlet:
return threading.current_thread
def _fetch_current_thread_functor():
# Until https://github.com/eventlet/eventlet/issues/172 is resolved
# or addressed we have to use complicated workaround to get a object
# that will not be recycled; the usage of threading.current_thread()
@@ -134,14 +132,16 @@ class ReaderWriterLock(object):
return eventlet.getcurrent
return threading.current_thread
def __init__(self, find_eventlet=True,
condition_cls=threading.Condition):
def __init__(self,
condition_cls=threading.Condition,
current_thread_functor=None):
self._writer = None
self._pending_writers = collections.deque()
self._readers = collections.deque()
self._cond = condition_cls()
self._current_thread = self._fetch_current_thread_functor(
find_eventlet=find_eventlet)
if current_thread_functor is None:
current_thread_functor = self._fetch_current_thread_functor()
self._current_thread = current_thread_functor
@property
def has_pending_writers(self):

View File

@@ -138,6 +138,23 @@ class _InterProcessLock(object):
def acquire(self, blocking=True,
delay=DELAY_INCREMENT, max_delay=MAX_DELAY,
timeout=None):
"""Attempt to acquire the given lock.
:param blocking: whether to wait forever to try to acquire the lock
:type blocking: bool
:param delay: when blocking this is the delay time in seconds that
will be added after each failed acquisition
:type delay: int/float
:param max_delay: the maximum delay to have (this limits the
accumulated delay(s) added after each failed
acquisition)
:type max_delay: int/float
:param timeout: an optional timeout (limits how long blocking
will occur for)
:type timeout: int/float
:returns: whether or not the acquisition succeeded
:rtype: bool
"""
if delay < 0:
raise ValueError("Delay must be greater than or equal to zero")
if timeout is not None and timeout < 0:
@@ -173,6 +190,7 @@ class _InterProcessLock(object):
return self
def release(self):
"""Release the previously acquired lock."""
if not self.acquired:
raise threading.ThreadError("Unable to release an unacquired"
" lock")
@@ -196,6 +214,7 @@ class _InterProcessLock(object):
self.release()
def exists(self):
"""Checks if the path that this lock exists at actually exists."""
return os.path.exists(self.path)
def trylock(self):

24
fasteners/version.py Normal file
View File

@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2014 Yahoo! Inc. All Rights Reserved.
# Copyright 2011 OpenStack Foundation.
#
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
_VERSION = "0.10"
def version_string():
return _VERSION

View File

@@ -31,7 +31,7 @@ install_requires = [
setup(
name='fasteners',
version='0.8.0',
version='0.10.0',
description='A python package that provides useful locks.',
author="Joshua Harlow",
author_email='harlowja@yahoo-inc.com',