From ab76d0c3dcea928a1f252ce827027aca834213cd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 14:05:48 +0200 Subject: Adding upstream version 2.14.13. Signed-off-by: Daniel Baumann --- lib/ansible/utils/lock.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 lib/ansible/utils/lock.py (limited to 'lib/ansible/utils/lock.py') diff --git a/lib/ansible/utils/lock.py b/lib/ansible/utils/lock.py new file mode 100644 index 0000000..34387dc --- /dev/null +++ b/lib/ansible/utils/lock.py @@ -0,0 +1,43 @@ +# Copyright (c) 2020 Matt Martz +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from functools import wraps + + +def lock_decorator(attr='missing_lock_attr', lock=None): + '''This decorator is a generic implementation that allows you + to either use a pre-defined instance attribute as the location + of the lock, or to explicitly pass a lock object. + + This code was implemented with ``threading.Lock`` in mind, but + may work with other locks, assuming that they function as + context managers. + + When using ``attr``, the assumption is the first argument to + the wrapped method, is ``self`` or ``cls``. + + Examples: + + @lock_decorator(attr='_callback_lock') + def send_callback(...): + + @lock_decorator(lock=threading.Lock()) + def some_method(...): + ''' + def outer(func): + @wraps(func) + def inner(*args, **kwargs): + # Python2 doesn't have ``nonlocal`` + # assign the actual lock to ``_lock`` + if lock is None: + _lock = getattr(args[0], attr) + else: + _lock = lock + with _lock: + return func(*args, **kwargs) + return inner + return outer -- cgit v1.2.3