diff --git a/Lib/ldap/ldapobject.py b/Lib/ldap/ldapobject.py index 7a9c17f6..b6f5efb0 100644 --- a/Lib/ldap/ldapobject.py +++ b/Lib/ldap/ldapobject.py @@ -28,6 +28,29 @@ from ldap import LDAPError +from errno import EINTR + +def _retry_on_interrupted_ldap_call(func, *args, **kwargs): + """ + Call func, retrying if it raises an LDAPError with errno == EINTR. + """ + + attempts = 0 + while True: + attempts += 1 + try: + return func(*args, **kwargs) + except LDAPError as e: + if attempts > 1: + raise e + try: + if 'errno' in e.args[0]: + if e.args[0]['errno'] == EINTR: + time.sleep(0.1) + continue + except IndexError: + pass + raise e class LDAPBytesWarning(BytesWarning): """Python 2 bytes mode warning""" @@ -125,7 +148,7 @@ def _ldap_call(self,func,*args,**kwargs): diagnostic_message_success = None try: try: - result = func(*args,**kwargs) + result = _retry_on_interrupted_ldap_call(func,*args,**kwargs) if __debug__ and self._trace_level>=2: if func.__name__!="unbind_ext": diagnostic_message_success = self._l.get_option(ldap.OPT_DIAGNOSTIC_MESSAGE)