Show More
@@ -31,6 +31,7 b' from rhodecode import __platform__, PLAT' | |||||
31 | # json |
|
31 | # json | |
32 | #============================================================================== |
|
32 | #============================================================================== | |
33 | from rhodecode.lib.ext_json import json |
|
33 | from rhodecode.lib.ext_json import json | |
|
34 | import array | |||
34 |
|
35 | |||
35 |
|
36 | |||
36 | #============================================================================== |
|
37 | #============================================================================== | |
@@ -415,6 +416,14 b' else:' | |||||
415 | # in py2.6 bytes is a synonim for str |
|
416 | # in py2.6 bytes is a synonim for str | |
416 | _bytes = str |
|
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 | # deque |
|
428 | # deque | |
420 | #============================================================================== |
|
429 | #============================================================================== | |
@@ -548,7 +557,127 b' else:' | |||||
548 | if __py_version__ >= (2, 6): |
|
557 | if __py_version__ >= (2, 6): | |
549 | from threading import Event, Thread |
|
558 | from threading import Event, Thread | |
550 | else: |
|
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 | def Event(*args, **kwargs): |
|
682 | def Event(*args, **kwargs): | |
554 | return _Event(*args, **kwargs) |
|
683 | return _Event(*args, **kwargs) |
@@ -24,7 +24,7 b' If not, see <http://www.gnu.org/licenses' | |||||
24 | ''' |
|
24 | ''' | |
25 | import os |
|
25 | import os | |
26 | import subprocess |
|
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 | class StreamFeeder(Thread): |
|
30 | class StreamFeeder(Thread): | |
@@ -39,7 +39,7 b' class StreamFeeder(Thread):' | |||||
39 | self.daemon = True |
|
39 | self.daemon = True | |
40 | filelike = False |
|
40 | filelike = False | |
41 | self.bytes = _bytes() |
|
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 | self.bytes = _bytes(source) |
|
43 | self.bytes = _bytes(source) | |
44 | else: # can be either file pointer or file-like |
|
44 | else: # can be either file pointer or file-like | |
45 | if type(source) in (int, long): # file pointer it is |
|
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