python: Fix the reference counting for python events placed on the eventq.
We need to add a reference when an object is put on the C++ queue, and remove a reference when the object is removed from the queue. This was not happening before and caused a memory problem.
This commit is contained in:
parent
1adfe5c7f3
commit
4e02e7c217
5 changed files with 40 additions and 23 deletions
|
@ -36,7 +36,7 @@ mainq = internal.event.cvar.mainEventQueue
|
|||
def create(obj, priority=None):
|
||||
if priority is None:
|
||||
priority = internal.event.Event.Default_Pri
|
||||
return internal.event.PythonEvent(obj, priority)
|
||||
return PythonEvent(obj, priority)
|
||||
|
||||
class Event(PythonEvent):
|
||||
def __init__(self, priority=None):
|
||||
|
|
|
@ -41,6 +41,35 @@
|
|||
|
||||
#pragma SWIG nowarn=350,351
|
||||
|
||||
%extend EventQueue {
|
||||
void
|
||||
schedule(Event *event, Tick when)
|
||||
{
|
||||
// Any python event that are scheduled must have their
|
||||
// internal object's refcount incremented so that the object
|
||||
// sticks around while it is in the event queue.
|
||||
PythonEvent *pyevent = dynamic_cast<PythonEvent *>(event);
|
||||
if (pyevent)
|
||||
pyevent->incref();
|
||||
$self->schedule(event, when);
|
||||
}
|
||||
|
||||
void
|
||||
deschedule(Event *event)
|
||||
{
|
||||
$self->deschedule(event);
|
||||
|
||||
// Now that we're removing the python object from the event
|
||||
// queue, we need to decrement its reference count.
|
||||
PythonEvent *pyevent = dynamic_cast<PythonEvent *>(event);
|
||||
if (pyevent)
|
||||
pyevent->decref();
|
||||
}
|
||||
}
|
||||
|
||||
%ignore EventQueue::schedule;
|
||||
%ignore EventQueue::deschedule;
|
||||
|
||||
%import "base/fast_alloc.hh"
|
||||
%import "sim/serialize.hh"
|
||||
|
||||
|
|
|
@ -38,15 +38,10 @@ PythonEvent::PythonEvent(PyObject *obj, Priority priority)
|
|||
{
|
||||
if (object == NULL)
|
||||
panic("Passed in invalid object");
|
||||
|
||||
Py_INCREF(object);
|
||||
|
||||
setFlags(AutoDelete);
|
||||
}
|
||||
|
||||
PythonEvent::~PythonEvent()
|
||||
{
|
||||
Py_DECREF(object);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -65,6 +60,10 @@ PythonEvent::process()
|
|||
async_event = true;
|
||||
async_exception = true;
|
||||
}
|
||||
|
||||
// Since the object has been removed from the event queue, its
|
||||
// reference count must be decremented.
|
||||
Py_DECREF(object);
|
||||
}
|
||||
|
||||
CountedDrainEvent *
|
||||
|
@ -85,17 +84,3 @@ cleanupCountedDrain(Event *counted_drain)
|
|||
assert(event->getCount() == 0);
|
||||
delete event;
|
||||
}
|
||||
|
||||
#if 0
|
||||
Event *
|
||||
create(PyObject *object, Event::Priority priority)
|
||||
{
|
||||
return new PythonEvent(object, priority);
|
||||
}
|
||||
|
||||
void
|
||||
destroy(Event *event)
|
||||
{
|
||||
delete event;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,9 @@ class PythonEvent : public Event
|
|||
PythonEvent(PyObject *obj, Event::Priority priority);
|
||||
~PythonEvent();
|
||||
|
||||
void incref() { Py_INCREF(object); }
|
||||
void decref() { Py_DECREF(object); }
|
||||
|
||||
virtual void process();
|
||||
};
|
||||
|
||||
|
|
|
@ -299,9 +299,9 @@ class EventQueue : public Serializable
|
|||
virtual const std::string name() const { return objName; }
|
||||
|
||||
// schedule the given event on this queue
|
||||
void schedule(Event *ev, Tick when);
|
||||
void deschedule(Event *ev);
|
||||
void reschedule(Event *ev, Tick when, bool always = false);
|
||||
void schedule(Event *event, Tick when);
|
||||
void deschedule(Event *event);
|
||||
void reschedule(Event *event, Tick when, bool always = false);
|
||||
|
||||
Tick nextTick() const { return head->when(); }
|
||||
Event *serviceOne();
|
||||
|
|
Loading…
Reference in a new issue