gpio.c: Added ISR thread termination flag
Also modified ISR handler logic to account for the flag. This fixes isrExit() deadlock in Python interactive mode and prevents a more generic problem of a spurious ISR call after mraa_gpio_isr_exit() is run. Closes #268. Signed-off-by: Alex Tereschenko <alext.mkrs@gmail.com> Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
This commit is contained in:
committed by
Brendan Le Foll
parent
3059c06fa0
commit
e6c3dd24a6
@@ -47,6 +47,7 @@ struct _gpio {
|
||||
void *isr_args; /**< args return when interupt service request triggered */
|
||||
pthread_t thread_id; /**< the isr handler thread id */
|
||||
int isr_value_fp; /**< the isr file pointer on the value */
|
||||
mraa_boolean_t isr_thread_terminating; /**< is the isr thread being terminated? */
|
||||
mraa_boolean_t owner; /**< If this context originally exported the pin */
|
||||
mraa_result_t (*mmap_write) (mraa_gpio_context dev, int value);
|
||||
int (*mmap_read) (mraa_gpio_context dev);
|
||||
|
||||
@@ -87,6 +87,7 @@ mraa_gpio_init_internal(mraa_adv_func_t* func_table, int pin)
|
||||
|
||||
dev->value_fp = -1;
|
||||
dev->isr_value_fp = -1;
|
||||
dev->isr_thread_terminating = 0;
|
||||
dev->phy_pin = -1;
|
||||
|
||||
// then check to make sure the pin is exported.
|
||||
@@ -229,7 +230,7 @@ mraa_gpio_interrupt_handler(void* arg)
|
||||
|
||||
for (;;) {
|
||||
ret = mraa_gpio_wait_interrupt(dev->isr_value_fp);
|
||||
if (ret == MRAA_SUCCESS) {
|
||||
if (ret == MRAA_SUCCESS && !dev->isr_thread_terminating) {
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||
#ifdef SWIGPYTHON
|
||||
// In order to call a python object (all python functions are objects) we
|
||||
@@ -258,7 +259,7 @@ mraa_gpio_interrupt_handler(void* arg)
|
||||
#endif
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||
} else {
|
||||
// we must have got an error code so die nicely
|
||||
// we must have got an error code or exit request so die nicely
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||
close(dev->isr_value_fp);
|
||||
dev->isr_value_fp = -1;
|
||||
@@ -344,6 +345,8 @@ mraa_gpio_isr_exit(mraa_gpio_context dev)
|
||||
if (dev->thread_id == 0 && dev->isr_value_fp == -1) {
|
||||
return ret;
|
||||
}
|
||||
// mark the beginning of the thread termination process for interested parties
|
||||
dev->isr_thread_terminating = 1;
|
||||
|
||||
// stop isr being useful
|
||||
ret = mraa_gpio_edge_mode(dev, MRAA_GPIO_EDGE_NONE);
|
||||
@@ -364,6 +367,7 @@ mraa_gpio_isr_exit(mraa_gpio_context dev)
|
||||
// assume our thread will exit either way we just lost it's handle
|
||||
dev->thread_id = 0;
|
||||
dev->isr_value_fp = -1;
|
||||
dev->isr_thread_terminating = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user