This loop is incorrect because if the first iteration of the cas-loop is successful, next will not be set on oldConnection and your linked-list will be emptied. It should look like this instead:

HttpConnection * next = connections;
do {
    oldConnection->next = next;
} while (!connections_.compare_exchange_weak(next, oldConnection));

This is a text book cas-loop: 1) read the variable, 2) modify it, 3) write it and loop back on failure. The fact that your code didn't follow this pattern was a dead-giveaway that there was something wrong :)