Private
Public Access
2
0

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:
Alex Tereschenko
2015-10-02 23:42:20 +02:00
committed by Brendan Le Foll
parent 3059c06fa0
commit e6c3dd24a6
2 changed files with 7 additions and 2 deletions

View File

@@ -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);

View File

@@ -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;
}