--- a/qmsk/net/lib/event2/base.pxd Sat Sep 26 22:09:24 2009 +0300
+++ b/qmsk/net/lib/event2/base.pxd Sat Sep 26 23:38:02 2009 +0300
@@ -9,11 +9,9 @@
An event_base stores the "global" state associated with events - it holds a set of events (pending/active/scheduled),
and uses some specific multiplexing method (select/poll/epoll/kqueue/etc) to drive these events.
- Constructs a new event_base with default parameters.
+
+ *** POSIX Signal Handling ***
- XXX: you must keep a reference to the event_base around yourself!
- XXX: what happens to events once we are destructed?
-
Libevent has its own asynchronous signal-handling mechanism that is incompatible with Python's signal-handling
mechanism.
@@ -31,14 +29,15 @@
This means that python's default signals and any other signals added using the signal module continue to work
at the cost of some additional complexity, but any libevent signal-events also work as well :)
- XXX: currently, you can only have one event_base at a time - there should be separate types used for the main
+ *** TODO ***
+
+ Currently, you can only have one event_base at a time - there should be separate types used for the main
thread and sub-threads, since the python signal handling mechanism only works in the main thread.
- XXX: the propagate-exceptions doesn't actually work either, it just aborts the event loop :)
+ The propagate-exceptions doesn't actually work either, it just aborts the event loop :)
- XXX: add support for event_config!
- XXX: add support for event_base_priority_init!
-
+ Support for event_config!
+ Support for event_base_priority_init!
"""
# the underlying ev_base object
--- a/qmsk/net/lib/event2/base.pyx Sat Sep 26 22:09:24 2009 +0300
+++ b/qmsk/net/lib/event2/base.pyx Sat Sep 26 23:38:02 2009 +0300
@@ -81,6 +81,9 @@
cdef class event_base :
def __init__ (self) :
+ """
+ Constructs a new event_base with default parameters.
+ """
# construct
self.ev_base = lib.event_base_new()
@@ -124,7 +127,7 @@
once - only run the event loop once, at most
nonblock - do not block waiting for events
- Returns True if succesfull, False if no events were registered
+ Returns True if the event loop exited, False if there were no more events to process
"""
cdef int flags = 0
--- a/test/lib_event.py Sat Sep 26 22:09:24 2009 +0300
+++ b/test/lib_event.py Sat Sep 26 23:38:02 2009 +0300
@@ -1,7 +1,7 @@
import unittest
from qmsk.net.lib.event2.base import event_base
-from qmsk.net.lib.event2.event import event
+from qmsk.net.lib.event2.event import event, CallbackEvent
from qmsk.net.lib.event2.constants import *
import os
@@ -20,6 +20,7 @@
self.res = (mask == self.ev_in)
+
class TestEventBase (unittest.TestCase) :
"""
Simple event_base bits
@@ -42,6 +43,7 @@
self.assertFalse(self.ev_base.loop(nonblock=True))
+
class TestEvent (unittest.TestCase) :
"""
Simple event bits.
@@ -126,6 +128,93 @@
ev = event(self.ev_base, 0, 0)
ev.add()
+
+ def test_init_nonalive (self) :
+ """
+ An event is not alive after init
+ """
+
+ ev = event(self.ev_base, 0, 0)
+
+ self.assertFalse(ev.alive)
+
+ def test_add_alive (self) :
+ """
+ An event is considered alive and pending after add
+ """
+
+ ev = event(self.ev_base, 0, EV_READ)
+ ev.add()
+
+ self.assertTrue(ev.alive)
+
+ def test_del_nonalive (self) :
+ """
+ An event is not considered alive anymore after del
+ """
+
+ ev = event(self.ev_base, 0, EV_READ)
+ ev.add()
+
+ ev.delete()
+
+ self.assertFalse(ev.alive)
+
+ def test_fire_nonalive (self) :
+ """
+ An event is not considered alive anymore during callback execution the callback fires, nor afterwards
+ """
+
+ fired = []
+
+ def cb (ev, what) :
+ fired.append(1)
+
+ self.assertFalse(ev.alive)
+
+ ev = CallbackEvent(self.ev_base, 0, EV_READ, cb)
+ ev.add(-1)
+
+ self.ev_base.loop()
+
+ # fired
+ self.assertTrue(fired)
+
+ # not alive anymore
+ self.assertFalse(ev.alive)
+
+ def test_fire_add_alive (self) :
+ """
+ An event is considered alive if it is re-added during callback exec
+ """
+
+ ev = CallbackEvent(self.ev_base, 0, EV_READ,
+ lambda ev, what: ev.add()
+ )
+
+ ev.add(0)
+
+ self.ev_base.loop(once=True, nonblock=True)
+
+ # still alive
+ self.assertTrue(ev.alive)
+
+ def test_persistent_fire_alive (self) :
+ """
+ A persistent event is still considered alive during and after callback exec
+ """
+
+ ev = CallbackEvent(self.ev_base, 0, EV_READ,
+ lambda ev, what: self.assertTrue(ev.alive)
+ )
+
+ ev.add()
+
+ self.ev_base.loop(once=True, nonblock=True)
+
+ # persists -> stays alive
+ self.assertTrue(ev.alive)
+
class TestEventPipe (unittest.TestCase) :
"""