Qt4: check that index.isValid too
[vlc/asuraparaju-public.git] / src / extras / tdestroy.c
blobaeb43bbafc0b3ce0584e81f6147123e2eb4b8f7e
1 /**
2 * @file tdestroy.c
3 * @brief replacement for GNU tdestroy()
4 */
5 /*****************************************************************************
6 * Copyright (C) 2009 RĂ©mi Denis-Courmont
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
27 #include <stdlib.h>
28 #include <assert.h>
30 #include <vlc_common.h>
32 #ifdef HAVE_TDESTROY
33 void vlc_tdestroy (void *root, void (*freenode) (void *))
35 (void) root;
36 assert (freenode != NULL);
37 abort ();
40 #else
41 #include <search.h>
43 static struct
45 const void **tab;
46 size_t count;
47 vlc_mutex_t lock;
48 } list = { NULL, 0, VLC_STATIC_MUTEX };
50 static void list_nodes (const void *node, const VISIT which, const int depth)
52 (void) depth;
54 if (which != postorder && which != leaf)
55 return;
57 const void **tab = realloc (list.tab, sizeof (*tab) * (list.count + 1));
58 if (unlikely(tab == NULL))
59 abort ();
61 tab[list.count] = *(const void **)node;
62 list.tab = tab;
63 list.count++;
66 static struct
68 const void *node;
69 vlc_mutex_t lock;
70 } smallest = { NULL, VLC_STATIC_MUTEX };
72 static int cmp_smallest (const void *a, const void *b)
74 if (a == b)
75 return 0;
76 if (a == smallest.node)
77 return -1;
78 if (likely(b == smallest.node))
79 return +1;
80 abort ();
83 void vlc_tdestroy (void *root, void (*freenode) (void *))
85 const void **tab;
86 size_t count;
88 assert (freenode != NULL);
90 /* Enumerate nodes in order */
91 vlc_mutex_lock (&list.lock);
92 assert (list.count == 0);
93 twalk (root, list_nodes);
94 tab = list.tab;
95 count = list.count;
96 list.tab = NULL;
97 list.count = 0;
98 vlc_mutex_unlock (&list.lock);
100 /* Destroy the tree */
101 vlc_mutex_lock (&smallest.lock);
102 for (size_t i = 0; i < count; i++)
104 smallest.node = tab[i];
105 if (tdelete (smallest.node, &root, cmp_smallest) == NULL)
106 abort ();
108 vlc_mutex_unlock (&smallest.lock);
109 assert (root == NULL);
111 /* Destroy the nodes */
112 for (size_t i = 0; i < count; i++)
113 freenode ((void *)(tab[i]));
114 free (tab);
117 #endif