Blocking device read() call destroys gevent #72

Closed
wants to merge 3 commits into
from

Projects

None yet

3 participants

@nh2
nh2 commented Mar 26, 2013

Hey,

it's cool that you introduced gevent into the Python code, I think that makes many things much easier to write.

However, there is one issue with that: The hidraw.read(32) call is blocking and therefore stops all gevent threads.

It also introduced a bug that an initial gevent.sleep(1), as was written in the README example code so far, would delay all EEG data by one second even though this sleep was not in the main loop.

This change fixes all of this by doing this call from a separate real thread, simply forwarding all data to the existing gevent.Queue via threading Queues.

It would be even better to instead do an event driven read() (using select/epoll/kqueue techniques, so probably even gevent.select in our case), but as far as I know that is not cross-platform; the overhead introduced by the poll I have implemented is quite low and can be traded off for latency (the current default value is 1 ms).

I could not test the this with windows and OS-level decryption, so it would be great if somebody could have a short look if that still works as expected.

(By the way, you are doing a great job here. Emokit is super useful.)

nh2 added some commits Mar 25, 2013
@nh2 nh2 Fix render.py on Linux (wrong indent) 7c61759
@nh2 nh2 Fix blocking read() on EEG device file destroying gevent cooperative …
…multitasking.

When a file read() is issued, this blocks all gevent threads, making its cooperative multi-tasking useless.

This change introduces a separate real Python `threading` thread that does the read() for us and forwards the data into gevent queues via threading queues.

Before this, every gevent.sleep(0) would also significantly and unexpectedly change what the program does: It would start the next blocking read() from the device, which means that the more sleep(0) you write, the bigger does the packet queue grow. This was against a fundamental idea of cooperative multi-tasking: Two sleep(0) in a row should barely change what the program does.
906d953
@nh2 nh2 Fix misleading sleep(1) in example.
Currently, this delays all EEG data received by the main program by one second.
51ee57f
@qdot
Member
qdot commented Mar 26, 2013

Hmm. I should really write a gevent wrapper for cython_hidapi. And finish cython_hidapi. :|

@nh2
nh2 commented Jun 13, 2013

Any update on this? Hidapi or not, blocking read makes gevent cry :)

@qdot
Member
qdot commented Jun 14, 2013

Can you check the conflict in emotiv.py real quick? Looks like I pulled something in before landing your stuff that's conflicting and I'm not gonna have time to sort it out for a couple of days.

@bschumacher
Member

No more gevent, so closing.

@bschumacher bschumacher closed this Oct 4, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment