diff --git a/tornado/curl_httpclient.py b/tornado/curl_httpclient.py index ecaf13794..b7f482033 100644 --- a/tornado/curl_httpclient.py +++ b/tornado/curl_httpclient.py @@ -61,15 +61,6 @@ def initialize( # type: ignore self._fds: dict[int, int] = {} self._timeout: object | None = None - # libcurl has bugs that sometimes cause it to not report all - # relevant file descriptors and timeouts to TIMERFUNCTION/ - # SOCKETFUNCTION. Mitigate the effects of such bugs by - # forcing a periodic scan of all active requests. - self._force_timeout_callback = ioloop.PeriodicCallback( - self._handle_force_timeout, 1000 - ) - self._force_timeout_callback.start() - # Work around a bug in libcurl 7.29.0: Some fields in the curl # multi object are initialized lazily, and its destructor will # segfault if it is destroyed without having been used. Add @@ -80,7 +71,6 @@ def initialize( # type: ignore self._multi.remove_handle(dummy_curl_handle) def close(self) -> None: - self._force_timeout_callback.stop() if self._timeout is not None: self.io_loop.remove_timeout(self._timeout) for curl in self._curls: @@ -91,7 +81,6 @@ def close(self) -> None: # Set below properties to None to reduce the reference count of current # instance, because those properties hold some methods of current # instance that will case circular reference. - self._force_timeout_callback = None # type: ignore self._multi = None def fetch_impl( @@ -185,19 +174,6 @@ def _handle_timeout(self) -> None: if new_timeout >= 0: self._set_timeout(new_timeout) - def _handle_force_timeout(self) -> None: - """Called by IOLoop periodically to ask libcurl to process any - events it may have forgotten about. - """ - while True: - try: - ret, num_handles = self._multi.socket_all() - except pycurl.error as e: - ret = e.args[0] - if ret != pycurl.E_CALL_MULTI_PERFORM: - break - self._finish_pending_requests() - def _finish_pending_requests(self) -> None: """Process any requests that were completed by the last call to multi.socket_action. @@ -487,12 +463,12 @@ def write_function(b: bytes | bytearray) -> int: raise ValueError("Body must be None for GET request") request_buffer = BytesIO(utf8(request.body or "")) - def ioctl(cmd: int) -> None: - if cmd == curl.IOCMD_RESTARTREAD: # type: ignore - request_buffer.seek(0) + def seek(offset: int, origin: int) -> int: + request_buffer.seek(offset, origin) + return pycurl.SEEKFUNC_OK curl.setopt(pycurl.READFUNCTION, request_buffer.read) - curl.setopt(pycurl.IOCTLFUNCTION, ioctl) + curl.setopt(pycurl.SEEKFUNCTION, seek) if request.method == "POST": curl.setopt(pycurl.POSTFIELDSIZE, len(request.body or "")) else: