While working on the python plugin, I realised that the timeout system does not allow for notification when a timeout is removed. This has been fine up until now because he closures never needed to be cleaned up.
In the python plugin, I pass through a custom structure which needs to be cleaned up if the timeout is removed. This is almost certainly the cause of some horrible memory leaks for me. The attached patch is a simple solution to the problem. I think it should be good enough for most situations. I could maintain some sort of lookup inside my plugin, but I think other plugins would benefit from this. It is OK to go in or were there any comments?
>From 4cbf2a803d3203a71f2711851383e21688266a9b Mon Sep 17 00:00:00 2001 From: Mike Dransfield <[EMAIL PROTECTED]> Date: Mon, 23 Apr 2007 14:26:17 +0100 Subject: [PATCH] Add remove callback to timeouts --- include/compiz.h | 1 + plugins/gconf.c | 2 +- plugins/plane.c | 2 +- plugins/regex.c | 2 +- plugins/rotate.c | 4 ++-- plugins/scale.c | 1 + plugins/water.c | 6 +++--- src/display.c | 18 ++++++++++++------ src/event.c | 2 +- src/screen.c | 1 + src/window.c | 2 +- 11 files changed, 25 insertions(+), 16 deletions(-) diff --git a/include/compiz.h b/include/compiz.h index eb3f142..4417319 100644 --- a/include/compiz.h +++ b/include/compiz.h @@ -942,6 +942,7 @@ compGetDisplayOptions (CompDisplay *display, CompTimeoutHandle compAddTimeout (int time, CallBackProc callBack, + CallBackProc removeCallBack, void *closure); void diff --git a/plugins/gconf.c b/plugins/gconf.c index 5d42f35..b3f730f 100644 --- a/plugins/gconf.c +++ b/plugins/gconf.c @@ -1070,7 +1070,7 @@ gconfInitDisplay (CompPlugin *p, gconf_client_notify_add (gd->client, APP_NAME, gconfKeyChanged, d, NULL, NULL); - gd->timeoutHandle = compAddTimeout (KEY_CHANGE_TIMEOUT, gconfTimeout, 0); + gd->timeoutHandle = compAddTimeout (KEY_CHANGE_TIMEOUT, gconfTimeout, NULL, 0); return TRUE; } diff --git a/plugins/plane.c b/plugins/plane.c index e715234..6bd0b5e 100644 --- a/plugins/plane.c +++ b/plugins/plane.c @@ -188,7 +188,7 @@ moveViewport (CompScreen *screen, ps->dest_y = -screen->y; ps->timer = SCROLL_TIME; - ps->timeoutHandle = compAddTimeout (SCROLL_TIME, endMove, screen); + ps->timeoutHandle = compAddTimeout (SCROLL_TIME, endMove, NULL, screen); damageScreen (screen); } diff --git a/plugins/regex.c b/plugins/regex.c index 1387663..9865fad 100644 --- a/plugins/regex.c +++ b/plugins/regex.c @@ -342,7 +342,7 @@ regexInitDisplay (CompPlugin *p, /* one shot timeout to which will register the expression handler after all screens and windows have been initialized */ - compAddTimeout (0, regexRegisterExpHanlder, (void *) d); + compAddTimeout (0, regexRegisterExpHanlder, NULL, (void *) d); return TRUE; } diff --git a/plugins/rotate.c b/plugins/rotate.c index bf6bb95..b52c1fc 100644 --- a/plugins/rotate.c +++ b/plugins/rotate.c @@ -1165,7 +1165,7 @@ rotateEdgeFlip (CompScreen *s, { if (!rs->rotateHandle) rs->rotateHandle = - compAddTimeout (rd->flipTime, rotateFlipLeft, s); + compAddTimeout (rd->flipTime, rotateFlipLeft, NULL, s); rs->moving = TRUE; rs->moveTo -= 360.0f / s->hsize; @@ -1205,7 +1205,7 @@ rotateEdgeFlip (CompScreen *s, { if (!rs->rotateHandle) rs->rotateHandle = - compAddTimeout (rd->flipTime, rotateFlipRight, s); + compAddTimeout (rd->flipTime, rotateFlipRight, NULL, s); rs->moving = TRUE; rs->moveTo += 360.0f / s->hsize; diff --git a/plugins/scale.c b/plugins/scale.c index 42c777b..cc10d89 100644 --- a/plugins/scale.c +++ b/plugins/scale.c @@ -1774,6 +1774,7 @@ scaleHandleEvent (CompDisplay *d, ss->hoverHandle = compAddTimeout (time, scaleHoverTimeout, + NULL, s); scaleSelectWindowAt (s, x, y, focus); diff --git a/plugins/water.c b/plugins/water.c index d55b939..45cb004 100644 --- a/plugins/water.c +++ b/plugins/water.c @@ -1347,7 +1347,7 @@ waterToggleRain (CompDisplay *d, int delay; delay = wd->opt[WATER_DISPLAY_OPTION_RAIN_DELAY].value.i; - ws->rainHandle = compAddTimeout (delay, waterRainTimeout, s); + ws->rainHandle = compAddTimeout (delay, waterRainTimeout, NULL, s); } else { @@ -1378,7 +1378,7 @@ waterToggleWiper (CompDisplay *d, int delay; delay = 2000; - ws->wiperHandle = compAddTimeout (delay, waterWiperTimeout, s); + ws->wiperHandle = compAddTimeout (delay, waterWiperTimeout, NULL, s); } else { @@ -1586,7 +1586,7 @@ waterSetDisplayOption (CompPlugin *plugin, continue; compRemoveTimeout (ws->rainHandle); - ws->rainHandle = compAddTimeout (value->i, waterRainTimeout, s); + ws->rainHandle = compAddTimeout (value->i, waterRainTimeout, NULL, s); } return TRUE; } diff --git a/src/display.c b/src/display.c index ee092bf..6c4aa27 100644 --- a/src/display.c +++ b/src/display.c @@ -55,6 +55,7 @@ typedef struct _CompTimeout { int time; int left; CallBackProc callBack; + CallBackProc removeCallBack; void *closure; CompTimeoutHandle handle; } CompTimeout; @@ -863,7 +864,7 @@ setDisplayOption (CompDisplay *display, compRemoveTimeout (display->pingHandle); display->pingHandle = - compAddTimeout (o->value.i, pingTimeout, display); + compAddTimeout (o->value.i, pingTimeout, NULL, display); return TRUE; } break; @@ -1058,6 +1059,7 @@ addTimeout (CompTimeout *timeout) CompTimeoutHandle compAddTimeout (int time, CallBackProc callBack, + CallBackProc removeCallBack, void *closure) { CompTimeout *timeout; @@ -1066,10 +1068,11 @@ compAddTimeout (int time, if (!timeout) return 0; - timeout->time = time; - timeout->callBack = callBack; - timeout->closure = closure; - timeout->handle = lastTimeoutHandle++; + timeout->time = time; + timeout->callBack = callBack; + timeout->removeCallBack = removeCallBack; + timeout->closure = closure; + timeout->handle = lastTimeoutHandle++; if (lastTimeoutHandle == MAXSHORT) lastTimeoutHandle = 1; @@ -1102,6 +1105,9 @@ compRemoveTimeout (CompTimeoutHandle handle) else timeouts = t->next; + if (t->removeCallBack) + (*t->removeCallBack) (t->closure); + free (t); } } @@ -2548,7 +2554,7 @@ addDisplay (char *name) d->pingHandle = compAddTimeout (d->opt[COMP_DISPLAY_OPTION_PING_DELAY].value.i, - pingTimeout, d); + pingTimeout, NULL, d); return TRUE; } diff --git a/src/event.c b/src/event.c index 52cae89..3e7936c 100644 --- a/src/event.c +++ b/src/event.c @@ -2022,7 +2022,7 @@ handleEvent (CompDisplay *d, { d->autoRaiseWindow = w->id; d->autoRaiseHandle = - compAddTimeout (delay, autoRaiseTimeout, d); + compAddTimeout (delay, autoRaiseTimeout, NULL, d); } else updateWindowAttributes (w, diff --git a/src/screen.c b/src/screen.c index 68e8f41..e8b541b 100644 --- a/src/screen.c +++ b/src/screen.c @@ -674,6 +674,7 @@ addSequence (CompScreen *screen, if (!screen->startupSequenceTimeoutHandle) compAddTimeout (1000, startupSequenceTimeout, + NULL, screen); updateStartupFeedback (screen); diff --git a/src/window.c b/src/window.c index 8d29530..74fb51b 100644 --- a/src/window.c +++ b/src/window.c @@ -2580,7 +2580,7 @@ sendSyncRequest (CompWindow *w) w->syncBorderWidth = w->serverBorderWidth; if (!w->syncWaitHandle) - w->syncWaitHandle = compAddTimeout (1000, syncWaitTimeout, w); + w->syncWaitHandle = compAddTimeout (1000, syncWaitTimeout, NULL, w); } void -- 1.5.1
_______________________________________________ compiz mailing list compiz@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/compiz