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 */
|
void *isr_args; /**< args return when interupt service request triggered */
|
||||||
pthread_t thread_id; /**< the isr handler thread id */
|
pthread_t thread_id; /**< the isr handler thread id */
|
||||||
int isr_value_fp; /**< the isr file pointer on the value */
|
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_boolean_t owner; /**< If this context originally exported the pin */
|
||||||
mraa_result_t (*mmap_write) (mraa_gpio_context dev, int value);
|
mraa_result_t (*mmap_write) (mraa_gpio_context dev, int value);
|
||||||
int (*mmap_read) (mraa_gpio_context dev);
|
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->value_fp = -1;
|
||||||
dev->isr_value_fp = -1;
|
dev->isr_value_fp = -1;
|
||||||
|
dev->isr_thread_terminating = 0;
|
||||||
dev->phy_pin = -1;
|
dev->phy_pin = -1;
|
||||||
|
|
||||||
// then check to make sure the pin is exported.
|
// then check to make sure the pin is exported.
|
||||||
@@ -229,7 +230,7 @@ mraa_gpio_interrupt_handler(void* arg)
|
|||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
ret = mraa_gpio_wait_interrupt(dev->isr_value_fp);
|
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);
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||||
#ifdef SWIGPYTHON
|
#ifdef SWIGPYTHON
|
||||||
// In order to call a python object (all python functions are objects) we
|
// In order to call a python object (all python functions are objects) we
|
||||||
@@ -258,7 +259,7 @@ mraa_gpio_interrupt_handler(void* arg)
|
|||||||
#endif
|
#endif
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
|
||||||
} else {
|
} 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);
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||||
close(dev->isr_value_fp);
|
close(dev->isr_value_fp);
|
||||||
dev->isr_value_fp = -1;
|
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) {
|
if (dev->thread_id == 0 && dev->isr_value_fp == -1) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
// mark the beginning of the thread termination process for interested parties
|
||||||
|
dev->isr_thread_terminating = 1;
|
||||||
|
|
||||||
// stop isr being useful
|
// stop isr being useful
|
||||||
ret = mraa_gpio_edge_mode(dev, MRAA_GPIO_EDGE_NONE);
|
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
|
// assume our thread will exit either way we just lost it's handle
|
||||||
dev->thread_id = 0;
|
dev->thread_id = 0;
|
||||||
dev->isr_value_fp = -1;
|
dev->isr_value_fp = -1;
|
||||||
|
dev->isr_thread_terminating = 0;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user