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; }
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; }
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; }
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); }
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); }
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; }
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; }
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; }
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); }
bool ProcessRunLock::SetStopped () { WriteLock(m_rwlock); m_running = false; WriteUnlock(m_rwlock); return true; }
bool ProcessRunLock::SetRunning () { WriteLock(m_rwlock); m_running = true; WriteUnlock(m_rwlock); return true; }
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; }
/* 函数声明: 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; }
/*static*/ void VMAreaHash::Remove(VMArea* area) { WriteLock(); sTable.RemoveUnchecked(area); WriteUnlock(); }
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); }
/*static*/ void VMAreaHash::Insert(VMArea* area) { WriteLock(); sTable.InsertUnchecked(area); WriteUnlock(); }
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); }
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); }
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 } }
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; }
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); }
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(); }
void AmVelocityView::CommitUndo() { // WRITE SONG BLOCK AmSong* song = WriteLock(); if (song) LockedCommitUndo(song); WriteUnlock(song); // END WRITE SONG BLOCK }
void AmEventTimeView::IntControlFinished() { // WRITE SONG BLOCK AmSong* song = WriteLock(); if (song) LockedIntControlFinished(song); WriteUnlock(song); // END WRITE SONG BLOCK }
void AmChannelPressureControl::CommitUndo() { // WRITE SONG BLOCK AmSong* song = WriteLock(); if (song) LockedCommitUndo(song); WriteUnlock(song); // END WRITE SONG BLOCK }
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 }
void ResetUIntMap(UIntMap *map) { WriteLock(&map->lock); free(map->array); map->array = NULL; map->size = 0; map->maxsize = 0; WriteUnlock(&map->lock); }
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); }
bool cThreadLockRw::CheckLock() { bool rv = TryWriteLock(); if ( rv ) WriteUnlock(); return rv; }
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); }