Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added
- `WinMM` engine
### Changed
- `run` function in NavaThread
- `stop` function in NavaThread
- `README.md` updated
- Test system modified
- `Python 3.6` support dropped
Expand Down
24 changes: 17 additions & 7 deletions nava/thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def run(self):
try:
if self._target is not None:
if self._engine == Engine.WINSOUND or self._engine == Engine.WINMM:
_ = self._target(*self._args, **self._kwargs)
self._target(*self._args, **self._kwargs)
else:
while True:
self._play_process = self._target(*self._args, **self._kwargs)
Expand All @@ -64,14 +64,24 @@ def stop(self):
# The alias is scoped to the MCI (Media Control Interface) context of the thread that created it.
# So the main thread can’t “see” the alias created in the worker thread.
else:
if self._play_process is not None:
if self._play_process:
# Best-effort: close all standard streams
try:
self._play_process.stdout.close()
self._play_process.stdin.close()
self._play_process.stderr.close()
self._play_process.kill()
self._play_process.terminate()
except ProcessLookupError:
except AttributeError:
# One of the streams may be None or already detached
pass
finally:
self._play_process.wait()

# Try graceful termination
try:
self._play_process.terminate()
self._play_process.wait(timeout=1)
except (TimeoutError, ProcessLookupError):
# Fallback to force kill
try:
self._play_process.kill()
self._play_process.wait()
except (ProcessLookupError, ValueError):
pass