예제 #1
0
bool CReadWriteLock::WriteLock(DWORD dwMilliseconds)
{
	if (m_other) {
		if (m_other->WriteLock(dwMilliseconds)) {
			m_nWriteLocks++;
			return true;
		}
		else
			return false;
	}
	WaitForSingleObject(m_hAccessLock, INFINITE);
	m_nWriteLocks++;
	if (m_sState == 1) {
		ReleaseMutex(m_hAccessLock);
		if (WaitForSingleObject(m_hCanWrite, dwMilliseconds) == WAIT_TIMEOUT) {
			WriteUnlock();
			return false;
		}
	}
	else {
		if (m_sState == 0) {
			m_sState = 2;
			ResetEvent(m_hCanRead);
		}
		ReleaseMutex(m_hAccessLock);
		// Now, wait for any other write threads to finish
		if (WaitForSingleObject(m_hCanWrite, dwMilliseconds) == WAIT_TIMEOUT) {
			WriteUnlock();
			return false;
		}
	}
	return true;
}
예제 #2
0
ALenum NewThunkEntry(ALuint *index)
{
    ALenum *NewList;
    ALuint i;

    ReadLock(&ThunkLock);
    for(i = 0;i < ThunkArraySize;i++)
    {
        if(ExchangeInt(&ThunkArray[i], AL_TRUE) == AL_FALSE)
        {
            ReadUnlock(&ThunkLock);
            *index = i+1;
            return AL_NO_ERROR;
        }
    }
    ReadUnlock(&ThunkLock);

    WriteLock(&ThunkLock);
    NewList = realloc(ThunkArray, ThunkArraySize*2 * sizeof(*ThunkArray));
    if(!NewList)
    {
        WriteUnlock(&ThunkLock);
        ERR("Realloc failed to increase to %u entries!\n", ThunkArraySize*2);
        return AL_OUT_OF_MEMORY;
    }
    memset(&NewList[ThunkArraySize], 0, ThunkArraySize*sizeof(*ThunkArray));
    ThunkArraySize *= 2;
    ThunkArray = NewList;

    ThunkArray[i] = AL_TRUE;
    WriteUnlock(&ThunkLock);

    *index = i+1;
    return AL_NO_ERROR;
}
예제 #3
0
ALenum InsertUIntMapEntry(UIntMap *map, ALuint key, ALvoid *value)
{
    ALsizei pos = 0;

    WriteLock(&map->lock);
    if(map->size > 0)
    {
        ALsizei low = 0;
        ALsizei high = map->size - 1;
        while(low < high)
        {
            ALsizei mid = low + (high-low)/2;
            if(map->array[mid].key < key)
                low = mid + 1;
            else
                high = mid;
        }
        if(map->array[low].key < key)
            low++;
        pos = low;
    }

    if(pos == map->size || map->array[pos].key != key)
    {
        if(map->size == map->limit)
        {
            WriteUnlock(&map->lock);
            return AL_OUT_OF_MEMORY;
        }

        if(map->size == map->maxsize)
        {
            ALvoid *temp = NULL;
            ALsizei newsize;

            newsize = (map->maxsize ? (map->maxsize<<1) : 4);
            if(newsize >= map->maxsize)
                temp = realloc(map->array, newsize*sizeof(map->array[0]));
            if(!temp)
            {
                WriteUnlock(&map->lock);
                return AL_OUT_OF_MEMORY;
            }
            map->array = temp;
            map->maxsize = newsize;
        }

        if(pos < map->size)
            memmove(&map->array[pos+1], &map->array[pos],
                    (map->size-pos)*sizeof(map->array[0]));
        map->size++;
    }
    map->array[pos].key = key;
    map->array[pos].value = value;
    WriteUnlock(&map->lock);

    return AL_NO_ERROR;
}
예제 #4
0
AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum param, const ALint *values)
{
    ALCdevice *device;
    ALCcontext *context;
    ALbuffer *albuf;

    if(values)
    {
        switch(param)
        {
            case AL_UNPACK_BLOCK_ALIGNMENT_SOFT:
            case AL_PACK_BLOCK_ALIGNMENT_SOFT:
                alBufferi(buffer, param, values[0]);
                return;
        }
    }

    context = GetContextRef();
    if(!context) return;

    device = context->Device;
    LockBuffersRead(device);
    if((albuf=LookupBuffer(device, buffer)) == NULL)
        SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);

    if(!(values))
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
    switch(param)
    {
    case AL_LOOP_POINTS_SOFT:
        WriteLock(&albuf->lock);
        if(ReadRef(&albuf->ref) != 0)
        {
            WriteUnlock(&albuf->lock);
            SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, done);
        }
        if(values[0] >= values[1] || values[0] < 0 ||
           values[1] > albuf->SampleLen)
        {
            WriteUnlock(&albuf->lock);
            SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
        }

        albuf->LoopStart = values[0];
        albuf->LoopEnd = values[1];
        WriteUnlock(&albuf->lock);
        break;

    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }

done:
    UnlockBuffersRead(device);
    ALCcontext_DecRef(context);
}
예제 #5
0
AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer,
  ALsizei offset, ALsizei samples,
  ALenum channels, ALenum type, const ALvoid *data)
{
    ALCdevice *device;
    ALCcontext *context;
    ALbuffer *albuf;
    ALsizei align;

    context = GetContextRef();
    if(!context) return;

    device = context->Device;
    LockBuffersRead(device);
    if((albuf=LookupBuffer(device, buffer)) == NULL)
        SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
    if(!(samples >= 0 && offset >= 0))
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
    if(IsValidType(type) == AL_FALSE)
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);

    WriteLock(&albuf->lock);
    align = ATOMIC_LOAD_SEQ(&albuf->UnpackAlign);
    if(SanitizeAlignment(type, &align) == AL_FALSE)
    {
        WriteUnlock(&albuf->lock);
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
    }
    if(channels != (ALenum)albuf->FmtChannels)
    {
        WriteUnlock(&albuf->lock);
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }
    if(offset > albuf->SampleLen || samples > albuf->SampleLen-offset)
    {
        WriteUnlock(&albuf->lock);
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
    }
    if((samples%align) != 0)
    {
        WriteUnlock(&albuf->lock);
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
    }

    /* offset -> byte offset */
    offset *= FrameSizeFromFmt(albuf->FmtChannels, albuf->FmtType);
    ConvertData((char*)albuf->data+offset, (enum UserFmtType)albuf->FmtType,
                data, type, ChannelsFromFmt(albuf->FmtChannels), samples, align);
    WriteUnlock(&albuf->lock);

done:
    UnlockBuffersRead(device);
    ALCcontext_DecRef(context);
}
예제 #6
0
ALenum NewThunkEntry(ALuint *index)
{
    void *NewList;
    ALuint i;

    ReadLock(&ThunkLock);
    for(i = 0;i < ThunkArraySize;i++)
    {
        if(ATOMIC_EXCHANGE(ALenum, &ThunkArray[i], AL_TRUE, almemory_order_acq_rel) == AL_FALSE)
        {
            ReadUnlock(&ThunkLock);
            *index = i+1;
            return AL_NO_ERROR;
        }
    }
    ReadUnlock(&ThunkLock);

    WriteLock(&ThunkLock);
    /* Double-check that there's still no free entries, in case another
     * invocation just came through and increased the size of the array.
     */
    for(;i < ThunkArraySize;i++)
    {
        if(ATOMIC_EXCHANGE(ALenum, &ThunkArray[i], AL_TRUE, almemory_order_acq_rel) == AL_FALSE)
        {
            WriteUnlock(&ThunkLock);
            *index = i+1;
            return AL_NO_ERROR;
        }
    }

    NewList = al_calloc(16, ThunkArraySize*2 * sizeof(*ThunkArray));
    if(!NewList)
    {
        WriteUnlock(&ThunkLock);
        ERR("Realloc failed to increase to %u entries!\n", ThunkArraySize*2);
        return AL_OUT_OF_MEMORY;
    }
    memcpy(NewList, ThunkArray, ThunkArraySize*sizeof(*ThunkArray));
    al_free(ThunkArray);
    ThunkArray = NewList;
    ThunkArraySize *= 2;

    ATOMIC_STORE_SEQ(&ThunkArray[i], AL_TRUE);
    WriteUnlock(&ThunkLock);

    *index = i+1;
    return AL_NO_ERROR;
}
예제 #7
0
void
CNdasServiceStringConfig::Set(
	NDASSVC_CONFIG_STRING_TYPE Type, 
	LPCTSTR Value)
{
	SIZE_T i = (SIZE_T) Type;
	XTLASSERT(i < DEF_SIZE);
	if (i >= DEF_SIZE) return;

	WriteLock();

	LPCTSTR RegValueName = NSCONFIG_STRING_DEF[i].RegValueName;
	BOOL fSuccess = _NdasSystemCfg.SetValueEx(
		SubContainer,
		RegValueName, 
		Value);
	XTLASSERT(fSuccess);

	HRESULT hr = ::StringCchCopyN(
		m_data[i], MAX_STRING_VALUE_LEN, 
		Value, MAX_STRING_VALUE_LEN);
	if (!m_cached[i])
	{
		m_cached[i] = true;
	}

	WriteUnlock();

	return;
}
예제 #8
0
void
CNdasServiceBoolConfig::Set(
	NDASSVC_CONFIG_BOOL_TYPE Type, 
	BOOL Value)
{
	SIZE_T i = (SIZE_T) Type;
	XTLASSERT(i < DEF_SIZE);
	if (i >= DEF_SIZE) return;

	WriteLock();

	LPCTSTR RegValueName = NSCONFIG_BOOL_DEF[i].RegValueName;
	BOOL fSuccess = _NdasSystemCfg.SetValueEx(
		SubContainer, 
		RegValueName, 
		Value);
	XTLASSERT(fSuccess);

	m_data[i] = Value;
	if (!m_cached[i])
	{
		m_cached[i] = true;
	}

	WriteUnlock();

	return;
}
예제 #9
0
파일: alState.c 프로젝트: dns/CLove
AL_API ALvoid AL_APIENTRY alDistanceModel(ALenum value)
{
    ALCcontext *context;

    context = GetContextRef();
    if(!context) return;

    if(!(value == AL_INVERSE_DISTANCE || value == AL_INVERSE_DISTANCE_CLAMPED ||
         value == AL_LINEAR_DISTANCE || value == AL_LINEAR_DISTANCE_CLAMPED ||
         value == AL_EXPONENT_DISTANCE || value == AL_EXPONENT_DISTANCE_CLAMPED ||
         value == AL_NONE))
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);

    WriteLock(&context->PropLock);
    context->DistanceModel = value;
    if(!context->SourceDistanceModel)
    {
        if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
            UpdateListenerProps(context);
    }
    WriteUnlock(&context->PropLock);

done:
    ALCcontext_DecRef(context);
}
예제 #10
0
 bool ProcessRunLock::SetStopped ()
 {
     WriteLock(m_rwlock);
     m_running = false;
     WriteUnlock(m_rwlock);
     return true;
 }
예제 #11
0
 bool ProcessRunLock::SetRunning ()
 {
     WriteLock(m_rwlock);
     m_running = true;
     WriteUnlock(m_rwlock);
     return true;
 }
예제 #12
0
ALvoid *RemoveUIntMapKey(UIntMap *map, ALuint key)
{
    ALvoid *ptr = NULL;
    WriteLock(&map->lock);
    if(map->size > 0)
    {
        ALsizei low = 0;
        ALsizei high = map->size - 1;
        while(low < high)
        {
            ALsizei mid = low + (high-low)/2;
            if(map->array[mid].key < key)
                low = mid + 1;
            else
                high = mid;
        }
        if(map->array[low].key == key)
        {
            ptr = map->array[low].value;
            if(low < map->size-1)
                memmove(&map->array[low], &map->array[low+1],
                        (map->size-1-low)*sizeof(map->array[0]));
            map->size--;
        }
    }
    WriteUnlock(&map->lock);
    return ptr;
}
예제 #13
0
/*
函数声明:	BOOL CScriptFuncTable::Clear(long lTime)
函数功能:	释放表空间
参数说明:	
			[IN]long lTime	-	等待的最大时间
返 回 值:	BOOL  - 
编 写 人:	居卫华
完成日期:	2001-7-6
*/
bool CScriptFuncTable::Clear(long lTime)
{

	if (m_lock.WaitToWrite(lTime) != LOCKEX_ERR_OK)
	{
		return false;
	}

	//clear
	for (int i = 0; i < this->m_FuncNum; i ++)
	{
		if (table[i] != NULL)
		{
			delete table[i];
			table[i] = NULL;
		}
	}
	if (table) 
	{
		delete table;
		table = NULL;
	}

	m_FuncNum = 0;
	m_tableSize = 0;
	table = NULL;
	m_bOverWrite = TRUE;
	WriteUnlock();
	return true;
}
예제 #14
0
파일: VMArea.cpp 프로젝트: mariuz/haiku
/*static*/ void
VMAreaHash::Remove(VMArea* area)
{
	WriteLock();
	sTable.RemoveUnchecked(area);
	WriteUnlock();
}
예제 #15
0
AL_API ALvoid AL_APIENTRY alListenerf(ALenum param, ALfloat value)
{
    ALCcontext *context;

    context = GetContextRef();
    if(!context) return;

    WriteLock(&context->PropLock);
    switch(param)
    {
    case AL_GAIN:
        if(!(value >= 0.0f && isfinite(value)))
            SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
        context->Listener->Gain = value;
        break;

    case AL_METERS_PER_UNIT:
        if(!(value >= 0.0f && isfinite(value)))
            SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
        context->Listener->MetersPerUnit = value;
        break;

    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }
    if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
        UpdateListenerProps(context);

done:
    WriteUnlock(&context->PropLock);
    ALCcontext_DecRef(context);
}
예제 #16
0
파일: VMArea.cpp 프로젝트: mariuz/haiku
/*static*/ void
VMAreaHash::Insert(VMArea* area)
{
	WriteLock();
	sTable.InsertUnchecked(area);
	WriteUnlock();
}
예제 #17
0
AL_API void AL_APIENTRY alMidiSoundfontvSOFT(ALsizei count, const ALuint *ids)
{
    ALCdevice *device;
    ALCcontext *context;
    MidiSynth *synth;
    ALenum err;

    context = GetContextRef();
    if(!context) return;

    if(count < 0)
        SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);

    device = context->Device;
    synth = device->Synth;

    WriteLock(&synth->Lock);
    if(synth->State == AL_PLAYING || synth->State == AL_PAUSED)
        alSetError(context, AL_INVALID_OPERATION);
    else
    {
        err = V(synth,selectSoundfonts)(context, count, ids);
        if(err != AL_NO_ERROR)
            alSetError(context, err);
    }
    WriteUnlock(&synth->Lock);

done:
    ALCcontext_DecRef(context);
}
예제 #18
0
AL_API void AL_APIENTRY alListener3i(ALenum param, ALint value1, ALint value2, ALint value3)
{
    ALCcontext *context;

    switch(param)
    {
    case AL_POSITION:
    case AL_VELOCITY:
        alListener3f(param, (ALfloat)value1, (ALfloat)value2, (ALfloat)value3);
        return;
    }

    context = GetContextRef();
    if(!context) return;

    WriteLock(&context->PropLock);
    switch(param)
    {
    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }
    if(!ATOMIC_LOAD(&context->DeferUpdates, almemory_order_acquire))
        UpdateListenerProps(context);

done:
    WriteUnlock(&context->PropLock);
    ALCcontext_DecRef(context);
}
예제 #19
0
void SeqMeasureControl::HandleSignatureMsg(BMessage* msg)
{
	int32	measure;
	if (msg->FindInt32("measure", &measure) != B_OK) return;
	int32	beats = -1, beatvalue = -1;
	if (msg->FindInt32("beats", &beats) != B_OK) beats = -1;
	if (msg->FindInt32("beat value", &beatvalue) != B_OK) beatvalue = -1;

	if (beats < 1 || beatvalue < 1) {
		if ( Window() ) Window()->PostMessage(msg);
	} else {
		// WRITE SONG OR TRACK BLOCK
		AmSong*		song = WriteLock();
		if (song) {
#if 0
			if ( mTrackRef.IsValid() ) {
				AmTrack*	track = song ? song->Track(mTrackRef) : 0;
				if (track) track->SetSignature(measure, beats, beatvalue);
			} else {
#endif
				song->SetSignature(measure, beats, beatvalue);
#if 0
			}
#endif
		}
		WriteUnlock(song);
		// END WRITE SONG OR TRACK BLOCK
	}
}
예제 #20
0
void SeqMeasureControl::HandleMotionMsg(BMessage* msg)
{
	if (!mTrackWinProps) return;
	int32			measure, code;
	const char*		key;
	if (msg->FindInt32("measure", &measure) != B_OK) return;
	if (msg->FindInt32("code", &code) != B_OK) code = 0;
	if (msg->FindString(MOTION_KEY_STR, &key) != B_OK) key = NULL;
	AmMotionI*		motion = NULL;
	if (key) motion = AmGlobals().NewMotion(BString(key) );
	
	// WRITE TRACK BLOCK
	AmSong*			song = WriteLock();
	if (song) {
		AmTrackRef	trackRef = mTrackWinProps->OrderedTrackAt(0);
		AmTrack*	track = song->Track(trackRef);
		if (track) {
			if (code == MOTION_CLEAR) track->ClearMotion(measure);
			else track->SetMotion(measure, motion);
		}
	}
	WriteUnlock(song);
	// END WRITE SONG OR TRACK BLOCK

	delete motion;
}
예제 #21
0
AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat value)
{
    ALCcontext *context;
    ALeffectslot *slot;

    context = GetContextRef();
    if(!context) return;

    WriteLock(&context->PropLock);
    LockEffectSlotsRead(context);
    if((slot=LookupEffectSlot(context, effectslot)) == NULL)
        SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
    switch(param)
    {
    case AL_EFFECTSLOT_GAIN:
        if(!(value >= 0.0f && value <= 1.0f))
            SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, done);
        slot->Gain = value;
        break;

    default:
        SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
    }
    UpdateEffectSlotProps(slot);

done:
    UnlockEffectSlotsRead(context);
    WriteUnlock(&context->PropLock);
    ALCcontext_DecRef(context);
}
예제 #22
0
void DataPipe::SetGP(vector3di pos)
{
	unsigned l;

	GP = pos;

	WriteLock();
	status = DPIPE_BUSY;

	for (l = 0; l < HOLDCHUNKS; l++) {
		SaveChunk(l);
		chstat[l].s = DPCHK_QUEUE;
	}

#if HOLDCHUNKS == 1
	l = 0;

#elif HOLDCHUNKS == 9
	l = 1 * 3 + 1;

#else /*18 or 27*/
	l = 1 * 9 + 1 * 3 + 1;

#endif

#ifdef DPDEBUG
	dbg_print("[DP] SetGP(): [%d %d %d]",GP.X,GP.Y,GP.Z);
#endif

	MakeChunk(l,GP);
	UpdateModelsSceneRoot();

	status = DPIPE_IDLE;
	WriteUnlock();
}
예제 #23
0
void AmVelocityView::CommitUndo()
{
	// WRITE SONG BLOCK
	AmSong*		song = WriteLock();
	if (song) LockedCommitUndo(song);
	WriteUnlock(song);
	// END WRITE SONG BLOCK
}
예제 #24
0
void AmEventTimeView::IntControlFinished()
{
	// WRITE SONG BLOCK
	AmSong*		song = WriteLock();
	if (song) LockedIntControlFinished(song);
	WriteUnlock(song);
	// END WRITE SONG BLOCK
}
예제 #25
0
void AmChannelPressureControl::CommitUndo()
{
	// WRITE SONG BLOCK
	AmSong*		song = WriteLock();
	if (song) LockedCommitUndo(song);
	WriteUnlock(song);
	// END WRITE SONG BLOCK
}
예제 #26
0
void AmEventEndTimeView::SetNewTime(AmTime newTime)
{
	if (!mContainer || !mEvent) return;
	// WRITE TRACK BLOCK
	AmSong*		song = WriteLock();
	if (song) mContainer->SetEventEndTime(mEvent, newTime);
	WriteUnlock( song );
	// END WRITE TRACK BLOCK
}
예제 #27
0
void ResetUIntMap(UIntMap *map)
{
    WriteLock(&map->lock);
    free(map->array);
    map->array = NULL;
    map->size = 0;
    map->maxsize = 0;
    WriteUnlock(&map->lock);
}
예제 #28
0
void AmEventTimeView::SetNewTime(AmTime newTime)
{
	if (!mContainer || !mEvent) return;
	// WRITE SONG BLOCK
	AmSong*		song = WriteLock();
	if (song) mContainer->SetEventStartTime(mEvent, newTime);
	WriteUnlock(song);
	// END WRITE SONG BLOCK
	SendNotices(ARPMSG_TIME_VIEW_CHANGED);
}
예제 #29
0
bool
cThreadLockRw::CheckLock()
{
  bool rv = TryWriteLock();
  
  if ( rv )
       WriteUnlock();

  return rv;
}
예제 #30
0
void ResetUIntMap(UIntMap *map)
{
    WriteLock(&map->lock);
    al_free(map->keys);
    map->keys = NULL;
    map->values = NULL;
    map->size = 0;
    map->capacity = 0;
    WriteUnlock(&map->lock);
}