Freeing the cm_serverRef_t has proved to be a challenge to get it right.
We now pass a pointer to a pointer to the first object in the list to
the function. We must be very careful to not destroy the list as we walk
the contents of the list with the extra level of indirection. On the
other hand, when we are freeing members of the list which have reached
a refCount of zero, we must be sure to maintain the fiction of the extra
level of indirection.
void cm_FreeServerList(cm_serverRef_t** list)
{
cm_serverRef_t **current = list;
- cm_serverRef_t **next = 0;
+ cm_serverRef_t **nextp = 0;
+ cm_serverRef_t * next = 0;
lock_ObtainWrite(&cm_serverLock);
while (*current)
{
- next = &(*current)->next;
+ nextp = &(*current)->next;
if (--((*current)->refCount) == 0) {
+ next = *nextp;
cm_FreeServer((*current)->server);
free(*current);
- *current = *next;
+ *current = next;
} else {
- current = next;
+ current = nextp;
}
}