Interrupting a blocking function frolm another thread.

S

superhac007

I am using the python module nfqueue-bindings which is a nfqueue
packet intercepting module. It uses the following snippet of code to
start the process:

print "trying to run"
try:
q.try_run()
except KeyboardInterrupt, e:
print "interrupted"

The q.try_run() method blocks. I would like to be able to interrupt
this the same way you can hit control-c to unblock it, but from
another thread. Does anyone have any idea on how to do this? Is
there some sort of Exception I can generate from another thread that
would do this?

Thanks
 
A

Adam Skutt

I am using the python module nfqueue-bindings which is a nfqueue
packet intercepting module.  It uses the following snippet of code to
start the process:

print "trying to run"
try:
     q.try_run()
     except KeyboardInterrupt, e:
     print "interrupted"

The q.try_run() method blocks.   I would like to be able to interrupt
this the same way you can hit control-c to unblock it, but from
another thread.  Does anyone have any idea on how to do this?  Is
there some sort of Exception I can generate from another thread that
would do this?

The simplest and most reliable way will be to modify the asynchronous
I/O example at https://www.wzdftpd.net/redmine/projects/nfqueue-bindings/repository/entry/examples/nfq_asyncore.py
to do what you want. The classical way to accomplish this would be to
create a second I/O descriptor (via os.pipe or similiar) and wait for
that descriptor in the same async I/O loop. When you want to stop the
loop, send a message (could be a single byte) to the second descriptor
and then respond appropriately in your asynchronous I/O handler.

However, simply ignoring the nfqueue socket while doing other
processing might be acceptable too. I would read the documentation
and ask questions carefully before taking that approach, as it may
lead to lost data or other problems. The viability of this approach
depends heavily on your application.

Adam
 
S

superhac007

The simplest and most reliable way will be to modify the asynchronous
I/O example at https://www.wzdftpd.net/redmine/projects/nfqueue-bindings/repository/entry/examples/nfq_asyncore.py
to do what you want. The classical way to accomplish this would be to
create a second I/O descriptor (via os.pipe or similiar) and wait for
that descriptor in the same async I/O loop. When you want to stop the
loop, send a message (could be a single byte) to the second descriptor
and then respond appropriately in your asynchronous I/O handler.

However, simply ignoring the nfqueue socket while doing other
processing might be acceptable too. I would read the documentation
and ask questions carefully before taking that approach, as it may
lead to lost data or other problems. The viability of this approach
depends heavily on your application.

Adam

Thanks for the reply Adam. I am still confused with the example with the example you linked to. I have only been working with Python for a couple ofweeks, but I am fluent with C. Given the example you linked to, are you saying that this is the run loop for asynchronous comm that a end user of the module could use? Or is this something with the nfqueue-bindings module that I would I have to modify. I don't recognize the the main loop in the example.

I am not not worried about losing data, I just need to start and stop this from another thread.
 
A

Adam Skutt

Thanks for the reply Adam.  I am still confused with the example with the example you linked to.  I have only been working with Python for a couple of weeks, but I am fluent with C.  Given the example you linked to, are you saying that this is the run loop for asynchronous comm that a end user of the module could use?  Or is this something with the nfqueue-bindings module that I would I have to modify.  I don't recognize the the main loop in the example.

asyncore is a standard python module for handling asynchronous I/O
operations (i.e., select/poll operations). The main loop in that
example is handled by the 'asyncore.loop()' call, which just calls
select() in a loop until all channels are closed. You're looking at
the standard Python library technique for an asynchronous I/O event
loop.

asyncore.file_dispatcher enables use of asyncore.loop() with standard
UNIX FDs. nfqueue.queue objects provide access to their underlying
FDs so you can wait on them. asyncore.loop() is the main loop of the
application, performing endless select/poll waits and calling
'handle_read' whenever the netfilter FD has data for reading. You can
find more details about the module in the Python library docs.

Since your code is Linux specific, you can always call os.select() or
os.poll() if it makes you feel better, but I don't think that's going
to simplify anything here.

Hopefully that helps you.

Adam
 
S

superhac007

asyncore is a standard python module for handling asynchronous I/O
operations (i.e., select/poll operations).  The main loop in that
example is handled by the 'asyncore.loop()' call, which just calls
select() in a loop until all channels are closed.  You're looking at
the standard Python library technique for an asynchronous I/O event
loop.

asyncore.file_dispatcher enables use of asyncore.loop() with standard
UNIX FDs.  nfqueue.queue objects provide access to their underlying
FDs so you can wait on them.  asyncore.loop() is the main loop of the
application, performing endless select/poll waits and calling
'handle_read' whenever the netfilter FD has data for reading.  You can
find more details about the module in the Python library docs.

Since your code is Linux specific, you can always call os.select() or
os.poll() if it makes you feel better, but I don't think that's going
to simplify anything here.

Hopefully that helps you.

Adam

Thanks for the through explanation. I now know what I need to do.


Thanks again!
 
S

superhac007

Thanks for the through explanation. I now know what I need to do.


Thanks again!

Adam,

I got everything working today asynchronously with your help. I really appreciate the information that you provided. Since I am very new to Python development your input and direction greatly expedited what I needed. Its people like you that make the world a better place. If you ever need anything don't hesitate to email me personally.

In a nut a shell I ended up with a thread that had the following:

def startAsyncQ():
global stop
while stop != True:
asyncore.loop(count=1)

I could then could control the starting and stopping from another thread. It worked like a champ.

Again, Thanks for your help!!!!!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,744
Latest member
CortneyMcK

Latest Threads

Top