3 * @brief replacement for GNU tdestroy()
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 *****************************************************************************/
30 #include <vlc_common.h>
33 void vlc_tdestroy (void *root
, void (*freenode
) (void *))
36 assert (freenode
!= NULL
);
48 } list
= { NULL
, 0, VLC_STATIC_MUTEX
};
50 static void list_nodes (const void *node
, const VISIT which
, const int depth
)
54 if (which
!= postorder
&& which
!= leaf
)
57 const void **tab
= realloc (list
.tab
, sizeof (*tab
) * (list
.count
+ 1));
58 if (unlikely(tab
== NULL
))
61 tab
[list
.count
] = *(const void **)node
;
70 } smallest
= { NULL
, VLC_STATIC_MUTEX
};
72 static int cmp_smallest (const void *a
, const void *b
)
76 if (a
== smallest
.node
)
78 if (likely(b
== smallest
.node
))
83 void vlc_tdestroy (void *root
, void (*freenode
) (void *))
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
);
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
)
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
]));