Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import os
import atexit
import random
import signal
import struct
import sysv_ipc

Expand All @@ -31,6 +32,18 @@ def final():
atexit.register(final)


def _signal_handler(signum, frame): # pylint: disable=unused-argument
"""Handle SIGTERM/SIGINT to ensure cleanup runs"""
final()
raise SystemExit(1)


try:
signal.signal(signal.SIGTERM, _signal_handler)
except (OSError, ValueError):
pass # Not all environments allow signal handling


# pylint: disable=c-extension-no-member
class PulseIn:
"""PulseIn Class to read PWM signals"""
Expand Down Expand Up @@ -108,14 +121,26 @@ def _wait_receive_msg(self, timeout=0, type=2):

# pylint: enable=redefined-builtin

def __del__(self):
self.deinit()

def deinit(self):
"""Deinitialises the PulseIn and releases any hardware and software
resources for reuse."""
# Clean up after ourselves
self._process.terminate()
procs.remove(self._process)
self._mq.remove()
queues.remove(self._mq)
if self._process is not None:
self._process.terminate()
if self._process in procs:
procs.remove(self._process)
self._process = None
if self._mq is not None:
try:
self._mq.remove()
except sysv_ipc.ExistentialError:
pass # Already removed
if self._mq in queues:
queues.remove(self._mq)
self._mq = None

def __enter__(self):
"""No-op used by Context Managers."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import os
import atexit
import random
import signal
import sysv_ipc

DEBUG = False
Expand All @@ -30,6 +31,18 @@ def final():
atexit.register(final)


def _signal_handler(signum, frame): # pylint: disable=unused-argument
"""Handle SIGTERM/SIGINT to ensure cleanup runs"""
final()
raise SystemExit(1)


try:
signal.signal(signal.SIGTERM, _signal_handler)
except (OSError, ValueError):
pass # Not all environments allow signal handling


# pylint: disable=c-extension-no-member
class PulseIn:
"""PulseIn Class to read PWM signals"""
Expand Down Expand Up @@ -110,14 +123,26 @@ def _wait_receive_msg(self, timeout=0, type=2):

# pylint: enable=redefined-builtin

def __del__(self):
self.deinit()

def deinit(self):
"""Deinitialises the PulseIn and releases any hardware and software
resources for reuse."""
# Clean up after ourselves
self._process.terminate()
procs.remove(self._process)
self._mq.remove()
queues.remove(self._mq)
if self._process is not None:
self._process.terminate()
if self._process in procs:
procs.remove(self._process)
self._process = None
if self._mq is not None:
try:
self._mq.remove()
except sysv_ipc.ExistentialError:
pass # Already removed
if self._mq in queues:
queues.remove(self._mq)
self._mq = None

def __enter__(self):
"""No-op used by Context Managers."""
Expand Down
33 changes: 29 additions & 4 deletions src/adafruit_blinka/microcontroller/bcm283x/pulseio/PulseIn.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import os
import atexit
import random
import signal
import struct
import sysv_ipc

Expand All @@ -31,6 +32,18 @@ def final():
atexit.register(final)


def _signal_handler(signum, frame): # pylint: disable=unused-argument
"""Handle SIGTERM/SIGINT to ensure cleanup runs"""
final()
raise SystemExit(1)


try:
signal.signal(signal.SIGTERM, _signal_handler)
except (OSError, ValueError):
pass # Not all environments allow signal handling


# pylint: disable=c-extension-no-member
class PulseIn:
"""PulseIn Class to read PWM signals"""
Expand Down Expand Up @@ -112,14 +125,26 @@ def _wait_receive_msg(self, timeout=0, type=2):

# pylint: enable=redefined-builtin

def __del__(self):
self.deinit()

def deinit(self):
"""Deinitialises the PulseIn and releases any hardware and software
resources for reuse."""
# Clean up after ourselves
self._process.terminate()
procs.remove(self._process)
self._mq.remove()
queues.remove(self._mq)
if self._process is not None:
self._process.terminate()
if self._process in procs:
procs.remove(self._process)
self._process = None
if self._mq is not None:
try:
self._mq.remove()
except sysv_ipc.ExistentialError:
pass # Already removed
if self._mq in queues:
queues.remove(self._mq)
self._mq = None

def __enter__(self):
"""No-op used by Context Managers."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ def __init__(self, chip_id: str):
else:
self.num_lines = self.num_lines

def __del__(self):
if self._chip:
self._chip.close()
self._chip = None

def __repr__(self):
return self.id

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ def __init__(self, chip_id: str):
info = self._chip.get_info()
self.num_lines = info.num_lines

def __del__(self):
if self._chip:
self._chip.close()
self._chip = None

def __repr__(self):
return self.id

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ def __init__(self, pin_id):
self._chip = gpiod.chip("gpiochip0", gpiod.chip.OPEN_BY_NAME)
self._line = None

def __del__(self):
self.deinit()

def __repr__(self):
return str(self.id)

Expand Down Expand Up @@ -115,6 +118,15 @@ def init(self, mode=IN, pull=None):
else:
raise RuntimeError("Invalid mode for pin: %s" % self.id)

def deinit(self):
"""Release the pin and associated resources."""
if self._line:
self._line.release()
self._line = None
if self._chip:
self._chip.close()
self._chip = None

def value(self, val=None):
"""Set or return the Pin Value"""
if val is None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ def __init__(self, pin_id):
self._line_request = None

def __del__(self):
if self._line_request:
self._line_request.release()
self.deinit()

def __repr__(self):
return str(self.id)
Expand Down Expand Up @@ -89,6 +88,15 @@ def init(self, mode=IN, pull=None):
else:
raise RuntimeError("Invalid mode for pin: %s" % self.id)

def deinit(self):
"""Release the pin and associated resources."""
if self._line_request:
self._line_request.release()
self._line_request = None
if self._chip:
self._chip.close()
self._chip = None

def value(self, val=None):
"""Set or return the Pin Value"""
if val is None:
Expand Down
5 changes: 4 additions & 1 deletion src/digitalio.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ def switch_to_input(self, pull=None):

def deinit(self):
"""Deinitialize the Digital Pin"""
del self._pin
if self._pin is not None:
if hasattr(self._pin, "deinit"):
self._pin.deinit()
self._pin = None

@property
def direction(self):
Expand Down
Loading