Splitting testing and setting could introduce race conditions. Using an atomic test-and-set would solve that:

    if (__sync_bool_compare_and_swap(&cur->__active, 0, 1)) {
        return i;
    }