# Path: hurray/swmr/exithandler.py
# @contextlib.contextmanager
# def handle_exit(callback=None, append=False):
#     """A context manager which properly handles SIGTERM and SIGINT
#     (KeyboardInterrupt) signals, registering a function which is
#     guaranteed to be called after signals are received.
#     Also, it makes sure to execute previously registered signal
#     handlers as well (if any).
# 
#     >>> app = App()
#     >>> with handle_exit(app.stop):
#     ...     app.start()
#     ...
#     >>>
# 
#     If append == False raise RuntimeError if there's already a handler
#     registered for SIGTERM, otherwise both new and old handlers are
#     executed in this order.
#     """
#     t = threading.current_thread()
#     if t.name != 'MainThread':
#         warnings.warn("!!! h5pySWMR warning: SIGTERM handling does not (yet) "
#                       "work in a threaded environment. Locks may not be "
#                       "released after process termination.", UserWarning)
#         yield
#         return
# 
#     old_handler = signal.signal(signal.SIGTERM, _sigterm_handler)
#     if old_handler != signal.SIG_DFL and old_handler != _sigterm_handler:
#         if not append:
#             raise RuntimeError("there is already a handler registered for "
#                                "SIGTERM: %r" % old_handler)
# 
#         def handler(signum, frame):
#             try:
#                 _sigterm_handler(signum, frame)
#             finally:
#                 old_handler(signum, frame)
#         signal.signal(signal.SIGTERM, handler)
# 
#     if _sigterm_handler.__enter_ctx__:
#         raise RuntimeError("can't use nested contexts")
#     _sigterm_handler.__enter_ctx__ = True
# 
#     try:
#         yield
#     except KeyboardInterrupt:
#         pass
#     except SystemExit as err:
#         # code != 0 refers to an application error (e.g. explicit
#         # sys.exit('some error') call).
#         # We don't want that to pass silently.
#         # Nevertheless, the 'finally' clause below will always
#         # be executed.
#         if err.code != 0:
#             raise
#     finally:
#         _sigterm_handler.__enter_ctx__ = False
#         if callback is not None:
#             callback()
# 
# Path: hurray/swmr/lock.py
# SWMR_SYNC = start_sync_manager()


from functools import wraps
from .exithandler import handle_exit
from .lock import SWMR_SYNC
# ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""
Simple function wrappers for read and write operations using the configured
strategy.  The acquisition of the read and write locks (start_read,
start_write) as well as the read and write operation itself _must_ be wrapped
with try/finally. Otherwise the corresponding locks cannot be
decremented/released if program execution ends, e.g., while performing a read
or write operation (because of a SIGTERM signal, for example).
"""




def reader(f):
    """
    Decorates methods reading a shared resource
    """

    @wraps(f)
    def func_wrapper(self, *args, **kwargs):
        """
        Wraps reading functions.
        """

# Path: hurray/swmr/exithandler.py
# @contextlib.contextmanager
# def handle_exit(callback=None, append=False):
#     """A context manager which properly handles SIGTERM and SIGINT
#     (KeyboardInterrupt) signals, registering a function which is
#     guaranteed to be called after signals are received.
#     Also, it makes sure to execute previously registered signal
#     handlers as well (if any).
# 
#     >>> app = App()
#     >>> with handle_exit(app.stop):
#     ...     app.start()
#     ...
#     >>>
# 
#     If append == False raise RuntimeError if there's already a handler
#     registered for SIGTERM, otherwise both new and old handlers are
#     executed in this order.
#     """
#     t = threading.current_thread()
#     if t.name != 'MainThread':
#         warnings.warn("!!! h5pySWMR warning: SIGTERM handling does not (yet) "
#                       "work in a threaded environment. Locks may not be "
#                       "released after process termination.", UserWarning)
#         yield
#         return
# 
#     old_handler = signal.signal(signal.SIGTERM, _sigterm_handler)
#     if old_handler != signal.SIG_DFL and old_handler != _sigterm_handler:
#         if not append:
#             raise RuntimeError("there is already a handler registered for "
#                                "SIGTERM: %r" % old_handler)
# 
#         def handler(signum, frame):
#             try:
#                 _sigterm_handler(signum, frame)
#             finally:
#                 old_handler(signum, frame)
#         signal.signal(signal.SIGTERM, handler)
# 
#     if _sigterm_handler.__enter_ctx__:
#         raise RuntimeError("can't use nested contexts")
#     _sigterm_handler.__enter_ctx__ = True
# 
#     try:
#         yield
#     except KeyboardInterrupt:
#         pass
#     except SystemExit as err:
#         # code != 0 refers to an application error (e.g. explicit
#         # sys.exit('some error') call).
#         # We don't want that to pass silently.
#         # Nevertheless, the 'finally' clause below will always
#         # be executed.
#         if err.code != 0:
#             raise
#     finally:
#         _sigterm_handler.__enter_ctx__ = False
#         if callback is not None:
#             callback()
# 
# Path: hurray/swmr/lock.py
# SWMR_SYNC = start_sync_manager()


# Path: hurray/swmr/sync.py
from functools import wraps
from .exithandler import handle_exit
from .lock import SWMR_SYNC

# ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""
Simple function wrappers for read and write operations using the configured
strategy.  The acquisition of the read and write locks (start_read,
start_write) as well as the read and write operation itself _must_ be wrapped
with try/finally. Otherwise the corresponding locks cannot be
decremented/released if program execution ends, e.g., while performing a read
or write operation (because of a SIGTERM signal, for example).
"""




def reader(f):
    """
    Decorates methods reading a shared resource
    """

    @wraps(f)
    def func_wrapper(self, *args, **kwargs):
        """
        Wraps reading functions.
        """

        with handle_exit(append=True):