static void RemoveActiveEffectSlots(const ALuint *slotids, ALsizei count, ALCcontext *context)
{
    struct ALeffectslotArray *curarray = ATOMIC_LOAD(&context->ActiveAuxSlots,
                                                     almemory_order_acquire);
    struct ALeffectslotArray *newarray = NULL;
    ALCdevice *device = context->Device;
    ALsizei i, j;

    /* Don't shrink the allocated array size since we don't know how many (if
     * any) of the effect slots to remove are in the array.
     */
    newarray = al_calloc(DEF_ALIGN, FAM_SIZE(struct ALeffectslotArray, slot, curarray->count));
    newarray->count = 0;
    for(i = 0;i < curarray->count;i++)
    {
        /* Insert this slot into the new array only if it's not one to remove. */
        ALeffectslot *slot = curarray->slot[i];
        for(j = count;j != 0;)
        {
            if(slot->id == slotids[--j])
                goto skip_ins;
        }
        newarray->slot[newarray->count++] = slot;
    skip_ins: ;
    }

    /* TODO: Could reallocate newarray now that we know it's needed size. */

    curarray = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, newarray, almemory_order_acq_rel);
    while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1))
        althrd_yield();
    al_free(curarray);
}
Exemple #2
0
int almtx_timedlock(almtx_t *mtx, const struct timespec *ts)
{
    int ret;

#ifdef HAVE_PTHREAD_MUTEX_TIMEDLOCK
    ret = pthread_mutex_timedlock(mtx, ts);
    switch(ret)
    {
        case 0: return althrd_success;
        case ETIMEDOUT: return althrd_timedout;
        case EBUSY: return althrd_busy;
    }
    return althrd_error;
#else
    if(!mtx || !ts)
        return althrd_error;

    while((ret=almtx_trylock(mtx)) == althrd_busy)
    {
        struct timespec now;

        if(ts->tv_sec < 0 || ts->tv_nsec < 0 || ts->tv_nsec >= 1000000000 ||
           altimespec_get(&now, AL_TIME_UTC) != AL_TIME_UTC)
            return althrd_error;
        if(now.tv_sec > ts->tv_sec || (now.tv_sec == ts->tv_sec && now.tv_nsec >= ts->tv_nsec))
            return althrd_timedout;

        althrd_yield();
    }

    return ret;
#endif
}
Exemple #3
0
void alcall_once(alonce_flag *once, void (*callback)(void))
{
    LONG ret;
    while((ret=InterlockedExchange(once, 1)) == 1)
        althrd_yield();
    if(ret == 0)
        (*callback)();
    InterlockedExchange(once, 2);
}
static void AddActiveEffectSlots(const ALuint *slotids, ALsizei count, ALCcontext *context)
{
    struct ALeffectslotArray *curarray = ATOMIC_LOAD(&context->ActiveAuxSlots,
                                                     almemory_order_acquire);
    struct ALeffectslotArray *newarray = NULL;
    ALsizei newcount = curarray->count + count;
    ALCdevice *device = context->Device;
    ALsizei i, j;

    /* Insert the new effect slots into the head of the array, followed by the
     * existing ones.
     */
    newarray = al_calloc(DEF_ALIGN, FAM_SIZE(struct ALeffectslotArray, slot, newcount));
    newarray->count = newcount;
    for(i = 0;i < count;i++)
        newarray->slot[i] = LookupEffectSlot(context, slotids[i]);
    for(j = 0;i < newcount;)
        newarray->slot[i++] = curarray->slot[j++];
    /* Remove any duplicates (first instance of each will be kept). */
    for(i = 1;i < newcount;i++)
    {
        for(j = i;j != 0;)
        {
            if(UNLIKELY(newarray->slot[i] == newarray->slot[--j]))
            {
                newcount--;
                for(j = i;j < newcount;j++)
                    newarray->slot[j] = newarray->slot[j+1];
                i--;
                break;
            }
        }
    }

    /* Reallocate newarray if the new size ended up smaller from duplicate
     * removal.
     */
    if(UNLIKELY(newcount < newarray->count))
    {
        struct ALeffectslotArray *tmpnewarray = al_calloc(DEF_ALIGN,
            FAM_SIZE(struct ALeffectslotArray, slot, newcount));
        memcpy(tmpnewarray, newarray, FAM_SIZE(struct ALeffectslotArray, slot, newcount));
        al_free(newarray);
        newarray = tmpnewarray;
        newarray->count = newcount;
    }

    curarray = ATOMIC_EXCHANGE_PTR(&context->ActiveAuxSlots, newarray, almemory_order_acq_rel);
    while((ATOMIC_LOAD(&device->MixCount, almemory_order_acquire)&1))
        althrd_yield();
    al_free(curarray);
}
static void RemoveEffectSlotList(ALCcontext *context, const ALeffectslot *slot)
{
    ALCdevice *device = context->Device;
    const ALeffectslot *root, *next;

    root = slot;
    next = ATOMIC_LOAD(&slot->next);
    if(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALeffectslot*, &context->ActiveAuxSlotList, &root, next))
    {
        const ALeffectslot *cur;
        do {
            cur = root;
            root = slot;
        } while(!ATOMIC_COMPARE_EXCHANGE_STRONG(ALeffectslot*, &cur->next, &root, next));
    }
    /* Wait for any mix that may be using these effect slots to finish. */
    while((ReadRef(&device->MixCount)&1) != 0)
        althrd_yield();
}
Exemple #6
0
int almtx_timedlock(almtx_t *mtx, const struct timespec *ts)
{
    int ret;

    if(!mtx || !ts)
        return althrd_error;

    while((ret=almtx_trylock(mtx)) == althrd_busy)
    {
        struct timespec now;

        if(ts->tv_sec < 0 || ts->tv_nsec < 0 || ts->tv_nsec >= 1000000000 ||
           altimespec_get(&now, AL_TIME_UTC) != AL_TIME_UTC)
            return althrd_error;
        if(now.tv_sec > ts->tv_sec || (now.tv_sec == ts->tv_sec && now.tv_nsec >= ts->tv_nsec))
            return althrd_timedout;

        althrd_yield();
    }

    return ret;
}
Exemple #7
0
static void opensl_stop_playback(ALCdevice *Device)
{
    osl_data *data = Device->ExtraData;
    SLPlayItf player;
    SLAndroidSimpleBufferQueueItf bufferQueue;
    SLresult result;

    result = VCALL(data->bufferQueueObject,GetInterface)(SL_IID_PLAY, &player);
    PRINTERR(result, "bufferQueue->GetInterface");
    if(SL_RESULT_SUCCESS == result)
    {
        result = VCALL(player,SetPlayState)(SL_PLAYSTATE_STOPPED);
        PRINTERR(result, "player->SetPlayState");
    }

    result = VCALL(data->bufferQueueObject,GetInterface)(SL_IID_BUFFERQUEUE, &bufferQueue);
    PRINTERR(result, "bufferQueue->GetInterface");
    if(SL_RESULT_SUCCESS == result)
    {
        result = VCALL0(bufferQueue,Clear)();
        PRINTERR(result, "bufferQueue->Clear");
    }
    if(SL_RESULT_SUCCESS == result)
    {
        SLAndroidSimpleBufferQueueState state;
        do {
            althrd_yield();
            result = VCALL(bufferQueue,GetState)(&state);
        } while(SL_RESULT_SUCCESS == result && state.count > 0);
        PRINTERR(result, "bufferQueue->GetState");
    }

    free(data->buffer);
    data->buffer = NULL;
    data->bufferSize = 0;
}