Ticket #1930 (new enhancement )

Opened 3 years ago

Last modified 1 year ago

create a libevent reactor

Reported by: PenguinOfDoom Assigned to: therve
Type: enhancement Priority: highest
Milestone: Component: core
Keywords: Cc: therve, antoine
Branch: branches/libevent-1930-4 Author: therve
Launchpad Bug:

Description

libevent provides primitives similar to addReader/addWriter/callLater. These could be used in a reactor.

Attachments

1930_libeventreactor_1.py (3.6 kB) - added by therve 3 years ago.
Basic implementation of libevent reactor
libevent.dll (48.0 kB) - added by bigdog 2 years ago.
windows libevent.dll built with visual studio 2003
_libevent.pyd (27.5 kB) - added by therve 2 years ago.
test.patch (9.7 kB) - added by antoine 1 year ago.
libevent-gc.patch (17.0 kB) - added by antoine 1 year ago.

Change History

  2006-07-17 13:33:30+00:00 changed by exarkun

  • owner changed from glyph to PenguinOfDoom
  • priority changed from normal to low

  2006-07-20 10:21:01+00:00 changed by therve

  • attachment 1930_libeventreactor_1.py added

Basic implementation of libevent reactor

  2006-07-20 10:22:29+00:00 changed by therve

I've tried to make a libevent reactor, but I'm a bit stuck for now (some segfaults appear in the tests). I attach my current work if somebody is interested.

  2006-07-20 10:22:42+00:00 changed by therve

  • cc set to therve

  2006-07-21 09:22:20+00:00 changed by therve

OK I've found the problem in libevent/eventmodule.c, in function __libevent_ev_callback (a problem with reference counting).

I have a fix, but I'm waiting for the livent-python to be up to see if it's not already corrected in the trunk. I'll send it to anyone interested.

  2006-07-24 09:18:50+00:00 changed by therve

It seems lots of work has been done here: source:/branches/slyphon/libevent-4/, using the libevent C bindings directly with Pyrex (I used the python bindings), and implementing callLater (I just did the FD management).

  2007-03-30 18:03:04+00:00 changed by bigdog

  • attachment libevent.dll added

windows libevent.dll built with visual studio 2003

  2007-03-30 18:52:28+00:00 changed by bigdog

If you need to build libevent on windows

1) #include <winsock2.h> must appear before #include<windows.h>

2) windows does not support function , create a macro that defined function

3) add #pragma to pull in socket lib (not sure if this is required for use in twisted/python. It was required to link the test app.

  2007-03-31 08:05:49+00:00 changed by therve

  • attachment _libevent.pyd added

  2007-03-31 08:13:24+00:00 changed by therve

I attached a build of the module for windows. I had to do some little hack to make it build. The tests doesn't pass for now, I'll probably need some help for this.

Oh, and I think using libevent in Windows use select, some that may not be that interesting (for now at least).

  2007-05-03 09:17:52+00:00 changed by therve

  • keywords set to review
  • owner deleted
  • priority changed from low to highest

The branch libevent-1930-2 is in pretty good shape. The main missing thing is Windows support, but it would need some Windows hero.

  2007-08-13 15:02:48+00:00 changed by exarkun

  • keywords deleted
  • owner set to therve
  • test_libevent
    • test_tim eout is bad :/ I'm not really sure what should be done about it, but something needs to be. real-time using tests will fail spuriously. test_loop has a similar timing issue, and is also quite long.
    • test_signalHandler is scary.
  • libeventreactor.py
    • hooray per-instance state
    • reads/writes/selectables should probably be private. they should be doc'd, too. if you want to copy some strings out of the closed-socket-1537-3 branch for this, that's cool. I imagine some refactoring is on the horizon.
  • _libevent.c
    • I think EventBase_New leaks memory when event_init fails.
    • I think EventBase_CreateEvent leaks memory when either Event_Init or PyObject_CallMethod("setEventBase") fails.
    • __libevent_ev_callback calls several Python APIs (Py_DECREF, Py_CLEAR, PyErr_WriteUnraisable) without holding the interpreter lock. The comment about how exceptions are handled has the right general idea, but neither WriteUnraisable? nor SetAsyncExc? is proper. I think terminating the event loop actually is the right thing to do. If I understand correctly, this will actually only cause dispatch() to raise. A reactor implemented with this module can handle the exception there and then call dispatch again. A first pass of this reactor might continue to use PyErr_WriteUnraisable (albeit correctly), but if there's no pressing need to merge this branch (as I think there isn't), doing it the right way now might make sense.
    • In Event_SetEventBase, Py_XDECREF is used after a NULL check. Might as well drop the check and use Py_DECREF, since that's the only difference between the two.
    • There might be something fishy about the order of execution at the end of Event_SetEventBase. I wonder if decref'ing the existing eventBase could ever result in the new eventBase being freed. If the existing eventBase held the only reference to the new one, and nothing else held a reference to the existing eventBase, then the new eventBase would be freed immediately before the Py_INCREF call saves it. Then the function would probably crash.

  2007-08-14 09:04:34+00:00 changed by therve

(In [21069])

  • Remote time related tests
  • Add some missing decrefs
  • Cleanups

Refs #1930

  2007-12-11 17:57:50+00:00 changed by therve

(In [22068]) Remove a stupid test, some cleanups.

Refs #1930

  2007-12-11 17:59:42+00:00 changed by therve

  • branch set to branches/libevent-1930-3
  • author set to therve

(In [22069]) Branching to 'libevent-1930-3'

  2008-01-04 21:22:23+00:00 changed by antoine

Hi

since I wanted something fun to do I created some tests to check for refcount problems. Attaching patch: there are some failures :-)

  2008-01-04 22:00:30+00:00 changed by therve

(In [22263]) Apply patch from antoine, adding failing tests for refcounting.

Refs #1930

  2008-01-04 22:05:52+00:00 changed by antoine

Oops, I have attached an updated version just before you committed the patch. There are a few more tests for persistent events.

  2008-01-04 23:06:23+00:00 changed by antoine

After playing a bit, it seems the flag EV_PERSIST does not make sense for pure timers, so the persist parameter to createTimer should probably be removed. Unless I've missed something :)

  2008-01-04 23:39:30+00:00 changed by antoine

  • attachment test.patch added

  2008-01-05 00:20:39+00:00 changed by antoine

I take back what I said, EV_PERSIST does make sense for "timers" because a timer is actually the loop timeout event. Sorry for posting too quick.

  2008-01-05 01:44:50+00:00 changed by antoine

  • attachment libevent-gc.patch added

  2008-01-05 01:49:04+00:00 changed by antoine

Here is a new patch against the current branch contents. It contains additional tests and also modifies _libevent.c so that all tests pass (by enabling proper garbage collection of Event and EventBase? objects, and maintaining internal structures to know which events are registered).

Unfortunately there is a remaining problem I haven't managed to fix: if I enable event_base_free(...) in the EventBase? deallocator, some tests fail with an assertion error in libevent. This deallocation call wasn't present in the original version either.

  2008-01-05 01:54:56+00:00 changed by antoine

  • cc changed from therve to therve, antoine

  2008-01-05 09:33:52+00:00 changed by therve

(In [22264]) Apply another patch, solving previous problems, with more tests.

Refs #1930

  2008-01-05 09:40:12+00:00 changed by therve

(In [22265]) Not all platforms raise EINPROGRESS, unfortunately.

Refs #1930

follow-up: ↓ 24   2008-01-05 09:53:14+00:00 changed by therve

Thanks a lot for the patch. I wasa wondering if we could use the libevent internal structures, and not storing the events on our own. But for now it does the trick.

  2008-01-05 10:27:06+00:00 changed by therve

(In [22266]) Remove some time related failures, cleanups.

Refs #1930

in reply to: ↑ 22   2008-01-05 14:53:21+00:00 changed by antoine

Replying to therve:

Thanks a lot for the patch. I wasa wondering if we could use the libevent internal structures, and not storing the events on our own. But for now it does the trick.

We could get rid of expiredEvents:

  • either by trusting libevent not to use the event struct once the callback returns (this is true in the current libevent version, 1.4.1-beta), so we can directly decref the EventObject? in the callback
  • or by using event_base_once() for non-persistent objects, but this is incompatible with the current Python API (which separates createEvent() and addToLoop()).

  2008-01-12 15:12:33+00:00 changed by therve

(In [22320]) Use Py_VISIT in traverse methods

Refs #1930

  2008-05-02 12:25:01+00:00 changed by therve

  • branch changed from branches/libevent-1930-3 to branches/libevent-1930-4

(In [23487]) Branching to 'libevent-1930-4'

Note: See TracTickets for help on using tickets.