0

I am using python with Raspian on the Raspberry pi. I have a peripheral attached that causes my interrupt handler function to run. Sometimes the interrupt get fired when the response to the first interrupt has not yet completed. So I added a variable that is set when the interrupt function is entered and reset when exited, and if upon entering the function, it finds that the lock is set it will immediately exit.

Is there a more standard way of dealing this kind of thing.

def IrqHandler(self, channel):
    if self.lockout: return
    self.lockout = True;
    # do stuff
    self.lockout = False;
spiderplant0
  • 3,872
  • 12
  • 52
  • 91
  • Your method seems fine. I'm not sure if it's possible because I don't have experience with the rpi, but is there a way of preventing the method from being called in the first place if lockout is true? – jstein123 Sep 24 '13 at 17:54

2 Answers2

2

You have a race condition if the IrqHandler is called twice sufficiently close together, both calls can see self.lockout as False and both proceed to set it to True etc.

The threading module has a Lock() object. Usually (the default) this is used to block a thread until the lock is released. This means that all the interrupts would be queued up and have a turn running the Handler.

You can also create a Lock(False) which will just return False if the Lock has been acquired. This is close to your use here

from threading import Lock

def __init__(self):
    self.irq_lock = Lock(False)

def IrqHandler(self, channel):
    if not self.irq_lock.acquire():
        return
    # do stuff
    self.irq_local.release()
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
  • Blocking the thread might not be the best response, as it will prevent the execution of the first interrupt handler. – Mark Ransom Sep 24 '13 at 18:05
  • @MarkRansom, It will depend on the application. For example, something like an alarm, might be ok to ignore triggers if you are already processing the alarm situation. – John La Rooy Sep 24 '13 at 18:13
  • Hi, thanks, but I'm gettign an error: `TypeError: allocate_lock() takes no arguments (1 given)` Are you using python 3 or something (i guess I should have said I'm on python 2) – spiderplant0 Sep 24 '13 at 18:36
  • I believe the 'False' argument should be in the call to acquire() and not Lock() – spiderplant0 Sep 24 '13 at 18:44
  • self.irq_local should be a typo of self.irq_lock – 林果皞 Jan 04 '14 at 02:24
0

You can tie that in with a borg pattern. This way you can have several interrupt instances paying attention to one state. There is another one called singleton but here is a discussion on the two. Why is the Borg pattern better than the Singleton pattern in Python

Community
  • 1
  • 1
Back2Basics
  • 7,406
  • 2
  • 32
  • 45
  • Thank, but I dont understand how I would use this in my situation. Do you mean I should create an instance of the singelton class and then destroy it so subsequent interrupts can re-instantiate it? – spiderplant0 Sep 24 '13 at 18:38