Esempio n. 1
0
    def test_no_double_writers(self):
        lock = fasteners.ReaderWriterLock()
        watch = _utils.StopWatch(duration=5)
        watch.start()
        dups = collections.deque()
        active = collections.deque()

        def acquire_check(me):
            with lock.write_lock():
                if len(active) >= 1:
                    dups.append(me)
                    dups.extend(active)
                active.append(me)
                try:
                    time.sleep(random.random() / 100)
                finally:
                    active.remove(me)

        def run():
            me = threading.current_thread()
            while not watch.expired():
                acquire_check(me)

        threads = []
        for i in range(0, self.THREAD_COUNT):
            t = _daemon_thread(run)
            threads.append(t)
            t.start()
        while threads:
            t = threads.pop()
            t.join()

        self.assertEqual([], list(dups))
        self.assertEqual([], list(active))
Esempio n. 2
0
    def _acquire(self,
                 blocking=True,
                 delay=DELAY_INCREMENT,
                 max_delay=MAX_DELAY,
                 timeout=None,
                 exclusive=True):

        if delay < 0:
            raise ValueError("Delay must be greater than or equal to zero")
        if timeout is not None and timeout < 0:
            raise ValueError("Timeout must be greater than or equal to zero")
        if delay >= max_delay:
            max_delay = delay
        self._do_open()
        watch = _utils.StopWatch(duration=timeout)
        r = _utils.Retry(delay,
                         max_delay,
                         sleep_func=self.sleep_func,
                         watch=watch)
        with watch:
            gotten = r(self._try_acquire, blocking, watch, exclusive)
        if not gotten:
            return False
        else:
            self.logger.log(
                _utils.BLATHER,
                "Acquired file lock `%s` after waiting %0.3fs [%s"
                " attempts were required]", self.path, watch.elapsed(),
                r.attempts)
            return True
Esempio n. 3
0
    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:
            raise ValueError("Timeout must be greater than or equal to zero")
        if delay >= max_delay:
            max_delay = delay
        try:
            self._do_open()
            watch = _utils.StopWatch(duration=timeout)
            r = _utils.Retry(delay,
                             max_delay,
                             sleep_func=self.sleep_func,
                             watch=watch)
            with watch:
                gotten = r(self._try_acquire, blocking, watch)
            if not gotten:
                self.acquired = False
                return False
            else:
                self.acquired = True
                self.logger.log(
                    _utils.BLATHER,
                    "Acquired file lock `%s` after waiting %0.3fs [%s"
                    " attempts were required]", self.path, watch.elapsed(),
                    r.attempts)
                return True
        finally:
            if not self.acquired:
                self._do_close()
Esempio n. 4
0
    def test_no_concurrent_readers_writers(self):
        lock = fasteners.ReaderWriterLock()
        watch = _utils.StopWatch(duration=5)
        watch.start()
        dups = collections.deque()
        active = collections.deque()

        def acquire_check(me, reader):
            if reader:
                lock_func = lock.read_lock
            else:
                lock_func = lock.write_lock
            with lock_func():
                if not reader:
                    # There should be no-one else currently active, if there
                    # is ensure we capture them so that we can later blow-up
                    # the test.
                    if len(active) >= 1:
                        dups.append(me)
                        dups.extend(active)
                active.append(me)
                try:
                    time.sleep(random.random() / 100)
                finally:
                    active.remove(me)

        def run():
            me = threading.current_thread()
            while not watch.expired():
                acquire_check(me, random.choice([True, False]))

        threads = []
        for i in range(0, self.THREAD_COUNT):
            t = _daemon_thread(run)
            threads.append(t)
            t.start()
        while threads:
            t = threads.pop()
            t.join()

        self.assertEqual([], list(dups))
        self.assertEqual([], list(active))