Skip to content

Commit

Permalink
Merge pull request #5 from /issues/4/close-in-sync-context
Browse files Browse the repository at this point in the history
Run trio.lowlevel.notify_closing only from aclose. Fixes #4
  • Loading branch information
joernheissler authored May 15, 2021
2 parents 8209aa3 + 4d97121 commit e8a0639
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 10 deletions.
7 changes: 4 additions & 3 deletions src/trio_serial/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def __del__(self) -> None:
"""
Destructor. Closes the port if still open.
"""
self.close()
self._close()

@property
def port(self) -> str:
Expand All @@ -170,10 +170,11 @@ async def aopen(self) -> None:
"""

@abstractmethod
def close(self) -> None:
def _close(self) -> None:
"""
Close the port as fast as possible, even if closing it quick+dirty.
If in doubt, use :py:meth:`aclose` or the async context manager.
Do not use this method directly. Instead use :py:meth:`aclose`
or the async context manager.
Do nothing if already closed.
"""
Expand Down
26 changes: 19 additions & 7 deletions src/trio_serial/posix.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ async def aclose(self) -> None:
"""
Close the port. Do nothing if already closed.
"""
self.close()
self._close(True)

async def aopen(self) -> None:
"""
Expand All @@ -85,17 +85,29 @@ async def aopen(self) -> None:
try:
self._reconfigure_port(force_update=True)
except BaseException:
self.close()
self._close()
raise

def close(self) -> None:
def _close(self, notify_closing: bool = False) -> None:
"""
Close the port. Do nothing if already closed.
Args:
notify_closing: Run trio's notify_closing: Any tasks waiting for the file descriptor
to become ready will be aborted immediately. This must only be set
in an async context.
"""
if self._fd is not None:
fd = self._fd
self._fd = None
trio.lowlevel.notify_closing(fd)
if self._fd is None:
return

fd = self._fd
self._fd = None
try:
# If the destructor is run this flag isn't required, because there cannot be
# any waiting tasks; if there were, the destructor wouldn't run.
if notify_closing:
trio.lowlevel.notify_closing(fd)
finally:
os.close(fd)

async def discard_input(self) -> None:
Expand Down

0 comments on commit e8a0639

Please sign in to comment.