Show More
@@ -31,6 +31,7 b' from rhodecode import __platform__, PLAT' | |||
|
31 | 31 | # json |
|
32 | 32 | #============================================================================== |
|
33 | 33 | from rhodecode.lib.ext_json import json |
|
34 | import array | |
|
34 | 35 | |
|
35 | 36 | |
|
36 | 37 | #============================================================================== |
@@ -415,6 +416,14 b' else:' | |||
|
415 | 416 | # in py2.6 bytes is a synonim for str |
|
416 | 417 | _bytes = str |
|
417 | 418 | |
|
419 | if __py_version__ >= (2, 6): | |
|
420 | _bytearray = bytearray | |
|
421 | else: | |
|
422 | # no idea if this is correct but all integration tests are passing | |
|
423 | # i think we never use bytearray anyway | |
|
424 | _bytearray = array | |
|
425 | ||
|
426 | ||
|
418 | 427 | #============================================================================== |
|
419 | 428 | # deque |
|
420 | 429 | #============================================================================== |
@@ -548,7 +557,127 b' else:' | |||
|
548 | 557 | if __py_version__ >= (2, 6): |
|
549 | 558 | from threading import Event, Thread |
|
550 | 559 | else: |
|
551 | from threading import _Verbose, Condition, Lock, Thread | |
|
560 | from threading import _Verbose, Condition, Lock, Thread, _time, \ | |
|
561 | _allocate_lock, RLock, _sleep | |
|
562 | ||
|
563 | def Condition(*args, **kwargs): | |
|
564 | return _Condition(*args, **kwargs) | |
|
565 | ||
|
566 | class _Condition(_Verbose): | |
|
567 | ||
|
568 | def __init__(self, lock=None, verbose=None): | |
|
569 | _Verbose.__init__(self, verbose) | |
|
570 | if lock is None: | |
|
571 | lock = RLock() | |
|
572 | self.__lock = lock | |
|
573 | # Export the lock's acquire() and release() methods | |
|
574 | self.acquire = lock.acquire | |
|
575 | self.release = lock.release | |
|
576 | # If the lock defines _release_save() and/or _acquire_restore(), | |
|
577 | # these override the default implementations (which just call | |
|
578 | # release() and acquire() on the lock). Ditto for _is_owned(). | |
|
579 | try: | |
|
580 | self._release_save = lock._release_save | |
|
581 | except AttributeError: | |
|
582 | pass | |
|
583 | try: | |
|
584 | self._acquire_restore = lock._acquire_restore | |
|
585 | except AttributeError: | |
|
586 | pass | |
|
587 | try: | |
|
588 | self._is_owned = lock._is_owned | |
|
589 | except AttributeError: | |
|
590 | pass | |
|
591 | self.__waiters = [] | |
|
592 | ||
|
593 | def __enter__(self): | |
|
594 | return self.__lock.__enter__() | |
|
595 | ||
|
596 | def __exit__(self, *args): | |
|
597 | return self.__lock.__exit__(*args) | |
|
598 | ||
|
599 | def __repr__(self): | |
|
600 | return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters)) | |
|
601 | ||
|
602 | def _release_save(self): | |
|
603 | self.__lock.release() # No state to save | |
|
604 | ||
|
605 | def _acquire_restore(self, x): | |
|
606 | self.__lock.acquire() # Ignore saved state | |
|
607 | ||
|
608 | def _is_owned(self): | |
|
609 | # Return True if lock is owned by current_thread. | |
|
610 | # This method is called only if __lock doesn't have _is_owned(). | |
|
611 | if self.__lock.acquire(0): | |
|
612 | self.__lock.release() | |
|
613 | return False | |
|
614 | else: | |
|
615 | return True | |
|
616 | ||
|
617 | def wait(self, timeout=None): | |
|
618 | if not self._is_owned(): | |
|
619 | raise RuntimeError("cannot wait on un-acquired lock") | |
|
620 | waiter = _allocate_lock() | |
|
621 | waiter.acquire() | |
|
622 | self.__waiters.append(waiter) | |
|
623 | saved_state = self._release_save() | |
|
624 | try: # restore state no matter what (e.g., KeyboardInterrupt) | |
|
625 | if timeout is None: | |
|
626 | waiter.acquire() | |
|
627 | if __debug__: | |
|
628 | self._note("%s.wait(): got it", self) | |
|
629 | else: | |
|
630 | # Balancing act: We can't afford a pure busy loop, so we | |
|
631 | # have to sleep; but if we sleep the whole timeout time, | |
|
632 | # we'll be unresponsive. The scheme here sleeps very | |
|
633 | # little at first, longer as time goes on, but never longer | |
|
634 | # than 20 times per second (or the timeout time remaining). | |
|
635 | endtime = _time() + timeout | |
|
636 | delay = 0.0005 # 500 us -> initial delay of 1 ms | |
|
637 | while True: | |
|
638 | gotit = waiter.acquire(0) | |
|
639 | if gotit: | |
|
640 | break | |
|
641 | remaining = endtime - _time() | |
|
642 | if remaining <= 0: | |
|
643 | break | |
|
644 | delay = min(delay * 2, remaining, .05) | |
|
645 | _sleep(delay) | |
|
646 | if not gotit: | |
|
647 | if __debug__: | |
|
648 | self._note("%s.wait(%s): timed out", self, timeout) | |
|
649 | try: | |
|
650 | self.__waiters.remove(waiter) | |
|
651 | except ValueError: | |
|
652 | pass | |
|
653 | else: | |
|
654 | if __debug__: | |
|
655 | self._note("%s.wait(%s): got it", self, timeout) | |
|
656 | finally: | |
|
657 | self._acquire_restore(saved_state) | |
|
658 | ||
|
659 | def notify(self, n=1): | |
|
660 | if not self._is_owned(): | |
|
661 | raise RuntimeError("cannot notify on un-acquired lock") | |
|
662 | __waiters = self.__waiters | |
|
663 | waiters = __waiters[:n] | |
|
664 | if not waiters: | |
|
665 | if __debug__: | |
|
666 | self._note("%s.notify(): no waiters", self) | |
|
667 | return | |
|
668 | self._note("%s.notify(): notifying %d waiter%s", self, n, | |
|
669 | n != 1 and "s" or "") | |
|
670 | for waiter in waiters: | |
|
671 | waiter.release() | |
|
672 | try: | |
|
673 | __waiters.remove(waiter) | |
|
674 | except ValueError: | |
|
675 | pass | |
|
676 | ||
|
677 | def notifyAll(self): | |
|
678 | self.notify(len(self.__waiters)) | |
|
679 | ||
|
680 | notify_all = notifyAll | |
|
552 | 681 | |
|
553 | 682 | def Event(*args, **kwargs): |
|
554 | 683 | return _Event(*args, **kwargs) |
@@ -24,7 +24,7 b' If not, see <http://www.gnu.org/licenses' | |||
|
24 | 24 | ''' |
|
25 | 25 | import os |
|
26 | 26 | import subprocess |
|
27 | from rhodecode.lib.compat import deque, Event, Thread, _bytes | |
|
27 | from rhodecode.lib.compat import deque, Event, Thread, _bytes, _bytearray | |
|
28 | 28 | |
|
29 | 29 | |
|
30 | 30 | class StreamFeeder(Thread): |
@@ -39,7 +39,7 b' class StreamFeeder(Thread):' | |||
|
39 | 39 | self.daemon = True |
|
40 | 40 | filelike = False |
|
41 | 41 | self.bytes = _bytes() |
|
42 | if type(source) in (type(''), _bytes, bytearray): # string-like | |
|
42 | if type(source) in (type(''), _bytes, _bytearray): # string-like | |
|
43 | 43 | self.bytes = _bytes(source) |
|
44 | 44 | else: # can be either file pointer or file-like |
|
45 | 45 | if type(source) in (int, long): # file pointer it is |
General Comments 0
You need to be logged in to leave comments.
Login now