BlackBerry: improve BPS event lifetime management
authorJonathan Hoffmann <jhoffmann@blackberry.com>
Thu, 12 Sep 2013 15:36:30 +0000 (11:36 -0400)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Thu, 31 Oct 2013 09:39:46 +0000 (10:39 +0100)
commitd358986d73049a3fb104355529dc1ebd7a83472c
tree7746a2a9e21c4ed776670d1fc7fe3c449e6491a1
parent87b2b0226b5fef964fd6898e30124a33c3ecec11
BlackBerry: improve BPS event lifetime management

In QEventDispatcherBlackberry::select(), if an event handler called
through filterEvent() starts a nested event loop by creating a new
QEventLoop, we will recursively enter the select() method again.
However, each time bps_get_event() is called, it destroys the last
event it handed out before returning the next event.  We don't want it
to destroy the event that triggered the nested event loop, since there
may still be more handlers that need to get that event, once the
nested event loop is done and control returns to the outer event loop.

So we move an event to a holding channel, which takes ownership of the
event.  Putting the event on our own channel allows us to manage when
it is destroyed, keeping it alive until we know we are done with it.
Each recursive call of this function needs to have it's own holding
channel, since a channel is a queue, not a stack.

However, a recursive call into the select() method happens very rarely
compared to the many times this method is called.  We don't want to
create a holding channel for each time this method is called, only
when it is called recursively.  Thus we have the instance variable
d->holding_channel to use in the common case.  We keep track of
recursive calls with d->loop_level.  If we are in a recursive call,
then we create a new holding channel for this run.

Backport from qtbase/5cc76dae7e985a7a39d839524dc8ad6475e597f3

Change-Id: Ib3584676d2db5a9a3754a1535d5fb6c9e14f5dbc
Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com>
src/corelib/kernel/qeventdispatcher_blackberry.cpp
src/corelib/kernel/qeventdispatcher_blackberry_p.h