Commit d0139df5 authored by Paul Eggert's avatar Paul Eggert

* image.c: Fix animation cache signature memory leak.

Fix some other minor performance problems while we're at it.
(imagemagick_create_cache): Clear just the members that
need clearing.  Don't set update_time, as caller does that now.
(imagemagick_prune_animation_cache, imagemagick_get_animation_cache):
Simplify by using pointer-to-pointer instead of a prev pointer.
(imagemagick_prune_animation_cache): Use make_emacs_time rather
than EMACS_TIME_FROM_DOUBLE, and DestroyString rather than free.
(imagemagick_get_animation_cache): Don't xstrdup the image signature;
it's already a copy.  Free the signature probe unless it's cached.
parent 22490125
2013-08-19 Paul Eggert <eggert@cs.ucla.edu> 2013-08-19 Paul Eggert <eggert@cs.ucla.edu>
* image.c: Fix animation cache signature memory leak.
Fix some other minor performance problems while we're at it.
(imagemagick_create_cache): Clear just the members that
need clearing. Don't set update_time, as caller does that now.
(imagemagick_prune_animation_cache, imagemagick_get_animation_cache):
Simplify by using pointer-to-pointer instead of a prev pointer.
(imagemagick_prune_animation_cache): Use make_emacs_time rather
than EMACS_TIME_FROM_DOUBLE, and DestroyString rather than free.
(imagemagick_get_animation_cache): Don't xstrdup the image signature;
it's already a copy. Free the signature probe unless it's cached.
* process.c (handle_child_signal): Fix crash; deleted pid (Bug#15106). * process.c (handle_child_signal): Fix crash; deleted pid (Bug#15106).
This was introduced by my 2013-08-12 fix for Bug#15035. This was introduced by my 2013-08-12 fix for Bug#15035.
......
...@@ -7890,9 +7890,11 @@ static struct animation_cache *animation_cache = NULL; ...@@ -7890,9 +7890,11 @@ static struct animation_cache *animation_cache = NULL;
static struct animation_cache * static struct animation_cache *
imagemagick_create_cache (char *signature) imagemagick_create_cache (char *signature)
{ {
struct animation_cache *cache = xzalloc (sizeof *cache); struct animation_cache *cache = xmalloc (sizeof *cache);
cache->signature = signature; cache->signature = signature;
cache->update_time = current_emacs_time (); cache->wand = 0;
cache->index = 0;
cache->next = 0;
return cache; return cache;
} }
...@@ -7900,30 +7902,22 @@ imagemagick_create_cache (char *signature) ...@@ -7900,30 +7902,22 @@ imagemagick_create_cache (char *signature)
static void static void
imagemagick_prune_animation_cache (void) imagemagick_prune_animation_cache (void)
{ {
struct animation_cache *cache = animation_cache; struct animation_cache **pcache = &animation_cache;
struct animation_cache *prev = NULL;
EMACS_TIME old = sub_emacs_time (current_emacs_time (), EMACS_TIME old = sub_emacs_time (current_emacs_time (),
EMACS_TIME_FROM_DOUBLE (60)); make_emacs_time (60, 0));
while (cache) while (*pcache)
{ {
if (EMACS_TIME_LT (cache->update_time, old)) struct animation_cache *cache = *pcache;
if (EMACS_TIME_LE (old, cache->update_time))
pcache = &cache->next;
else
{ {
struct animation_cache *this_cache = cache; DestroyString (cache->signature);
free (cache->signature);
if (cache->wand) if (cache->wand)
DestroyMagickWand (cache->wand); DestroyMagickWand (cache->wand);
if (prev) *pcache = cache->next;
prev->next = cache->next; xfree (cache);
else
animation_cache = cache->next;
cache = cache->next;
free (this_cache);
}
else
{
prev = cache;
cache = cache->next;
} }
} }
} }
...@@ -7931,26 +7925,26 @@ imagemagick_prune_animation_cache (void) ...@@ -7931,26 +7925,26 @@ imagemagick_prune_animation_cache (void)
static struct animation_cache * static struct animation_cache *
imagemagick_get_animation_cache (MagickWand *wand) imagemagick_get_animation_cache (MagickWand *wand)
{ {
char *signature = xstrdup (MagickGetImageSignature (wand)); char *signature = MagickGetImageSignature (wand);
struct animation_cache *cache; struct animation_cache *cache;
struct animation_cache **pcache = &animation_cache;
imagemagick_prune_animation_cache (); imagemagick_prune_animation_cache ();
cache = animation_cache; cache = animation_cache;
if (! cache) for (pcache = &animation_cache; *pcache; pcache = &cache->next)
{
animation_cache = imagemagick_create_cache (signature);
return animation_cache;
}
while (strcmp(signature, cache->signature) &&
cache->next)
cache = cache->next;
if (strcmp(signature, cache->signature))
{ {
cache->next = imagemagick_create_cache (signature); cache = *pcache;
return cache->next; if (! cache)
{
*pcache = cache = imagemagick_create_cache (signature);
break;
}
if (strcmp (signature, cache->signature) == 0)
{
DestroyString (signature);
break;
}
} }
cache->update_time = current_emacs_time (); cache->update_time = current_emacs_time ();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment