From ac69a4aa48b425551426dc2fb7db086811eb37b6 Mon Sep 17 00:00:00 2001 From: strunker Date: Tue, 20 Dec 2022 22:21:16 -0500 Subject: [PATCH 1/4] Added operating system specific code Added in os detection so that select and poll are correctly utilized dependent on running OS. --- pychromecast/socket_client.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/pychromecast/socket_client.py b/pychromecast/socket_client.py index c84a5ef66..0c1887612 100644 --- a/pychromecast/socket_client.py +++ b/pychromecast/socket_client.py @@ -17,6 +17,7 @@ import sys import threading import time +import platform from collections import defaultdict, namedtuple from struct import pack, unpack @@ -565,15 +566,20 @@ def run_once(self, timeout=POLL_TIME_NON_BLOCKING): # poll the socket, as well as the socketpair to allow us to be interrupted rlist = [self.socket, self.socketpair[0]] - # Map file descriptors to socket objects because select.select does not support fd > 1024 - # https://stackoverflow.com/questions/14250751/how-to-increase-filedescriptors-range-in-python-select - fd_to_socket = {rlist_item.fileno(): rlist_item for rlist_item in rlist} + operatingSystem = platform.uname().system try: - poll_obj = select.poll() - for poll_fd in rlist: - poll_obj.register(poll_fd, select.POLLIN) - poll_result = poll_obj.poll(timeout * 1000) # timeout in milliseconds - can_read = [fd_to_socket[fd] for fd, _status in poll_result] + if operatingSystem != "Windows": + # Map file descriptors to socket objects because select.select does not support fd > 1024 + # https://stackoverflow.com/questions/14250751/how-to-increase-filedescriptors-range-in-python-select + fd_to_socket = {rlist_item.fileno(): rlist_item for rlist_item in rlist} + + poll_obj = select.poll() + for poll_fd in rlist: + poll_obj.register(poll_fd, select.POLLIN) + poll_result = poll_obj.poll(timeout * 1000) # timeout in milliseconds + can_read = [fd_to_socket[fd] for fd, _status in poll_result] + else: + can_read, _, _ = select.select(rlist, [], [], timeout) except (ValueError, OSError) as exc: self.logger.error( "[%s(%s):%s] Error in select call: %s", From 94440df273e95d98a4b3fa277cfcdc5f51d9181f Mon Sep 17 00:00:00 2001 From: strunker Date: Sun, 25 Dec 2022 17:25:25 -0500 Subject: [PATCH 2/4] Removed os code added dir to select Added a check to see if poll is part of avail methods on select object. Fixes the windows vs linux problem. --- pychromecast/socket_client.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pychromecast/socket_client.py b/pychromecast/socket_client.py index 0c1887612..64ec3ca7c 100644 --- a/pychromecast/socket_client.py +++ b/pychromecast/socket_client.py @@ -17,7 +17,6 @@ import sys import threading import time -import platform from collections import defaultdict, namedtuple from struct import pack, unpack @@ -566,9 +565,9 @@ def run_once(self, timeout=POLL_TIME_NON_BLOCKING): # poll the socket, as well as the socketpair to allow us to be interrupted rlist = [self.socket, self.socketpair[0]] - operatingSystem = platform.uname().system + availableCommands = dir(select) try: - if operatingSystem != "Windows": + if "poll" in availableCommands: # Map file descriptors to socket objects because select.select does not support fd > 1024 # https://stackoverflow.com/questions/14250751/how-to-increase-filedescriptors-range-in-python-select fd_to_socket = {rlist_item.fileno(): rlist_item for rlist_item in rlist} From f0801cee753b4cc84638a5a6a0032d3869736edc Mon Sep 17 00:00:00 2001 From: strunker Date: Sun, 25 Dec 2022 20:50:45 -0500 Subject: [PATCH 3/4] Implemented has as part of class constructor the hasattr check should take place only once as part of the class constructor, we simply check the object property on any subsequent call to run_once. --- pychromecast/socket_client.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pychromecast/socket_client.py b/pychromecast/socket_client.py index 64ec3ca7c..1bf7bb229 100644 --- a/pychromecast/socket_client.py +++ b/pychromecast/socket_client.py @@ -229,6 +229,8 @@ def __init__( self.receiver_controller.register_status_listener(self) + self.hasSelectPoll = hasattr(select,"poll") + def initialize_connection( self, ): # pylint:disable=too-many-statements, too-many-branches @@ -565,9 +567,8 @@ def run_once(self, timeout=POLL_TIME_NON_BLOCKING): # poll the socket, as well as the socketpair to allow us to be interrupted rlist = [self.socket, self.socketpair[0]] - availableCommands = dir(select) try: - if "poll" in availableCommands: + if self.hasSelectPoll == True: # Map file descriptors to socket objects because select.select does not support fd > 1024 # https://stackoverflow.com/questions/14250751/how-to-increase-filedescriptors-range-in-python-select fd_to_socket = {rlist_item.fileno(): rlist_item for rlist_item in rlist} From 32b7b454fc73619570d4fb9217c8dc6877d343f5 Mon Sep 17 00:00:00 2001 From: strunker Date: Sun, 25 Dec 2022 21:00:06 -0500 Subject: [PATCH 4/4] Implemented poll check as a global. --- pychromecast/socket_client.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pychromecast/socket_client.py b/pychromecast/socket_client.py index 1bf7bb229..6955e262b 100644 --- a/pychromecast/socket_client.py +++ b/pychromecast/socket_client.py @@ -56,6 +56,8 @@ CONNECTION_STATUS_FAILED_RESOLVE = "FAILED_RESOLVE" # The socket connection was lost and needs to be retried CONNECTION_STATUS_LOST = "LOST" +# Check for select poll method +SELECT_HAS_POLL = hasattr(select,"poll") HB_PING_TIME = 10 HB_PONG_TIME = 10 @@ -229,8 +231,6 @@ def __init__( self.receiver_controller.register_status_listener(self) - self.hasSelectPoll = hasattr(select,"poll") - def initialize_connection( self, ): # pylint:disable=too-many-statements, too-many-branches @@ -568,7 +568,7 @@ def run_once(self, timeout=POLL_TIME_NON_BLOCKING): # poll the socket, as well as the socketpair to allow us to be interrupted rlist = [self.socket, self.socketpair[0]] try: - if self.hasSelectPoll == True: + if SELECT_HAS_POLL == True: # Map file descriptors to socket objects because select.select does not support fd > 1024 # https://stackoverflow.com/questions/14250751/how-to-increase-filedescriptors-range-in-python-select fd_to_socket = {rlist_item.fileno(): rlist_item for rlist_item in rlist}