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
[email protected]
http://lists.freedesktop.org/mailman/listinfo/compiz