RingStatus_t RingGeneric_c::Insert( unsigned int Value ) { unsigned int OldNextInsert; OS_LockMutex( &Lock ); OldNextInsert = NextInsert; Storage[NextInsert] = Value; NextInsert++; if( NextInsert == Limit ) NextInsert = 0; if( NextInsert == NextExtract ) { NextInsert = OldNextInsert; OS_UnLockMutex( &Lock ); return RingTooManyEntries; } OS_UnLockMutex( &Lock ); OS_SetEvent( &Signal ); return RingNoError; }
//////////////////////////////////////////////////////////////////////////// /// /// Release any buffers queued within the StreamBuffer structure. /// /// Pass any buffer held on the Manifestor_Audio_c::StreamBuffer structure /// onto the output ring. /// /// The super-class will tidy up an queued events. /// ManifestorStatus_t Manifestor_Audio_c::ReleaseQueuedDecodeBuffers() { ManifestorStatus_t Status; MANIFESTOR_DEBUG(">><<\n"); OS_LockMutex(&BufferQueueLock); // // Emit all the queued buffers // for (unsigned int BufferIndex = BufferQueueHead; BufferIndex != INVALID_BUFFER_ID; BufferIndex = StreamBuffer[BufferIndex].NextIndex) { Status = ReleaseBuffer(BufferIndex); if (Status != ManifestorNoError) { MANIFESTOR_ERROR("Sub-class got cross when we tried to release a buffer - ignoring them\n"); } QueuedBufferCount--; if (StreamBuffer[BufferIndex].EventPending) ServiceEventQueue(BufferIndex); OutputRing->Insert((unsigned int) StreamBuffer[BufferIndex].Buffer); } BufferQueueHead = INVALID_BUFFER_ID; BufferQueueTail = ANY_BUFFER_ID; OS_UnLockMutex(&BufferQueueLock); return Manifestor_Base_c::ReleaseQueuedDecodeBuffers(); }
BufferStatus_t BufferManager_Generic_c::DestroyPool(BufferPool_t Pool) { BufferPool_Generic_t LocalPool = (BufferPool_Generic_t)Pool; BufferPool_Generic_t *LocationOfPointer; // // First find and remove the pool from our list // OS_LockMutex(&Lock); for (LocationOfPointer = &ListOfBufferPools; *LocationOfPointer != NULL; LocationOfPointer = &((*LocationOfPointer)->Next)) if (*LocationOfPointer == LocalPool) break; if (*LocationOfPointer == NULL) { report(severity_error, "BufferManager_Generic_c::DestroyPool - Pool not found.\n"); OS_UnLockMutex(&Lock); return BufferPoolNotFound; } *LocationOfPointer = LocalPool->Next; OS_UnLockMutex(&Lock); // // Then destroy the actual pool // delete LocalPool; return BufferNoError; }
//}}} //{{{ DeletePlayback HavanaStatus_t HavanaPlayer_c::DeletePlayback (HavanaPlayback_c* HavanaPlayback) { int i; if (HavanaPlayback == NULL) return HavanaPlaybackInvalid; OS_LockMutex (&Lock); for (i = 0; i < MAX_PLAYBACKS; i++) { if (Playback[i] == HavanaPlayback) break; } if (i == MAX_PLAYBACKS) { HAVANA_ERROR("Unable to locate playback for delete\n"); OS_UnLockMutex (&Lock); return HavanaPlaybackInvalid; } delete HavanaPlayback; Playback[i] = NULL; OS_UnLockMutex (&Lock); return HavanaNoError; }
OS_Status_t OS_ResetEvent(OS_Event_t *Event) { OS_LockMutex(&((*Event)->Mutex)); (*Event)->Valid = false; OS_UnLockMutex(&((*Event)->Mutex)); return OS_NO_ERROR; }
BufferStatus_t BufferManager_Generic_c::CreatePool( BufferPool_t *Pool, BufferType_t Type, unsigned int NumberOfBuffers, unsigned int Size, void *MemoryPool[3], void *ArrayOfMemoryBlocks[][3], char *DeviceMemoryPartitionName) { BufferStatus_t Status; BufferDataDescriptor_t *Descriptor; BufferPool_Generic_t NewPool; // // Initialize the return parameter // *Pool = NULL; // // Get the descriptor // Status = GetDescriptor(Type, BufferDataTypeBase, &Descriptor); if (Status != BufferNoError) return Status; // // Perform simple parameter checks // if (Pool == NULL) { report(severity_error, "BufferManager_Generic_c::CreatePool - Null supplied as place to return Pool pointer.\n"); return BufferError; } if (Descriptor->AllocateOnPoolCreation && (NumberOfBuffers == NOT_SPECIFIED)) { report(severity_error, "BufferManager_Generic_c::CreatePool - Unable to allocate on creation, NumberOfBuffers not specified.\n"); return BufferParametersIncompatibleWithAllocationSource; } // // Perform the creation // NewPool = new BufferPool_Generic_c(this, Descriptor, NumberOfBuffers, Size, MemoryPool, ArrayOfMemoryBlocks, DeviceMemoryPartitionName); if ((NewPool == NULL) || (NewPool->InitializationStatus != BufferNoError)) { BufferStatus_t Status; Status = BufferInsufficientMemoryForPool; if (NewPool != NULL) Status = NewPool->InitializationStatus; report(severity_error, "BufferManager_Generic_c::CreatePool - Failed to create pool (%08x).\n", Status); return Status; } // // Insert the pool into our list // OS_LockMutex(&Lock); NewPool->Next = ListOfBufferPools; ListOfBufferPools = NewPool; OS_UnLockMutex(&Lock); // *Pool = NewPool; return BufferNoError; }
AllocatorStatus_t AllocatorSimple_c::Free(void) { int i; unsigned int LocalBufferSize; unsigned int MaxBlockSize; unsigned char *LocalOffset; OS_LockMutex(&Lock); memset(Blocks, 0x00, sizeof(Blocks)); LocalBufferSize = BufferSize; LocalOffset = NULL; MaxBlockSize = 0x4000000 - ((uintptr_t)PhysicalAddress & 0x03ffffff); HighestUsedBlockIndex = 0; for (i = 0; ((LocalBufferSize != 0) && (i < ALLOCATOR_SIMPLE_MAX_BLOCKS)); i++) { Blocks[i].InUse = true; Blocks[i].Size = min(LocalBufferSize, MaxBlockSize); Blocks[i].Base = LocalOffset; LocalBufferSize -= Blocks[i].Size; LocalOffset += Blocks[i].Size; MaxBlockSize = 0x4000000; HighestUsedBlockIndex = i; } OS_SetEvent(&EntryFreed); OS_UnLockMutex(&Lock); return AllocatorNoError; }
//////////////////////////////////////////////////////////////////////////// /// /// Populate the DecodeContext structure with parameters for MPEG audio. /// This can be over-ridden by WMA to not have any output buffer, as it will /// do an MME_SEND_BUFFERS instead of MME_TRANSFORM /// CodecStatus_t Codec_MmeAudio_c::FillOutDecodeContext(void) { CodecStatus_t Status; // // Obtain a new buffer if needed // if (CurrentDecodeBufferIndex == INVALID_INDEX) { Status = GetDecodeBuffer(); if (Status != CodecNoError) { report(severity_error, "Codec_MmeAudio_c::Input(%s) - Failed to get decode buffer.\n", Configuration.CodecName); ReleaseDecodeContext(DecodeContext); return Status; } } // // Record the buffer being used in the decode context // DecodeContext->BufferIndex = CurrentDecodeBufferIndex; // // Provide default values for the input and output buffers (the sub-class can change this if it wants to). // // Happily the audio firmware is less mad than the video firmware on the subject of buffers. // memset(&DecodeContext->MMECommand, 0x00, sizeof(MME_Command_t)); SetCommandIO(); OS_LockMutex(&Lock); DecodeContext->DecodeInProgress = true; BufferState[CurrentDecodeBufferIndex].DecodesInProgress++; BufferState[CurrentDecodeBufferIndex].OutputOnDecodesComplete = true; OS_UnLockMutex(&Lock); return CodecNoError; }
RingStatus_t RingGeneric_c::Extract( unsigned int *Value, unsigned int BlockingPeriod ) { // // If there is nothing in the ring we wait for upto the specified period. // OS_ResetEvent( &Signal ); if( (NextExtract == NextInsert) && (BlockingPeriod != RING_NONE_BLOCKING) ) OS_WaitForEvent( &Signal, BlockingPeriod ); OS_LockMutex( &Lock ); if( NextExtract != NextInsert ) { *Value = Storage[NextExtract]; NextExtract++; if( NextExtract == Limit ) NextExtract = 0; OS_UnLockMutex( &Lock ); return RingNoError; } OS_UnLockMutex( &Lock ); return RingNothingToGet; }
/* * This is where we actually do the stuff in GTK_system_loop. */ static gint gtk_idle_handler(gpointer *data) { int ret; // g_print("Timer = %d\n", TM_GetTicks()); OS_LockMutex(&command_mutex); while (TM_Ticked) { TM_TickHandler(0); // TM_Ticked--; TM_Ticked = 0; } ret = v9t9_return = v9t9_execute(); if (ret == em_TooFast) { #if defined(UNDER_UNIX) unix_system_pause(); #else win32_system_pause(); #endif } else if (ret == em_Quitting || ret == em_Dying) { gtk_main_quit(); return FALSE; } OS_UnlockMutex(&command_mutex); // continue to call me... :) return TRUE; }
//}}} //{{{ RemoveStream HavanaStatus_t HavanaPlayback_c::RemoveStream (class HavanaStream_c* HavanaStream) { int i; PLAYBACK_DEBUG("\n"); if (HavanaStream == NULL) return HavanaStreamInvalid; OS_LockMutex (&Lock); for (i = 0; i < MAX_STREAMS_PER_PLAYBACK; i++) { if (Stream[i] == HavanaStream) break; } if (i == MAX_STREAMS_PER_PLAYBACK) { PLAYBACK_ERROR("Unable to locate stream for delete\n"); OS_UnLockMutex (&Lock); return HavanaStreamInvalid; } //PLAYBACK_DEBUG ("Removing stream %p, %d\n", Stream[i], i); delete Stream[i]; Stream[i] = NULL; OS_UnLockMutex (&Lock); return HavanaNoError; }
OS_Status_t OS_SetEvent(OS_Event_t *Event) { OS_LockMutex(&((*Event)->Mutex)); (*Event)->Valid = true; OSDEV_WakeUpQueue((*Event)->Queue); OS_UnLockMutex(&((*Event)->Mutex)); return OS_NO_ERROR; }
OS_Status_t OS_ReInitializeEvent(OS_Event_t *Event) { OS_LockMutex(&((*Event)->Mutex)); (*Event)->Valid = false; OSDEV_ReInitializeWaitQueue((*Event)->Queue); OS_UnLockMutex(&((*Event)->Mutex)); return OS_NO_ERROR; }
DemultiplexorStatus_t Demultiplexor_Base_c::DestroyContext(DemultiplexorContext_t Context) { DemultiplexorBaseContext_t BaseContext = (DemultiplexorBaseContext_t)Context; OS_LockMutex(&BaseContext->Lock); OS_TerminateMutex(&BaseContext->Lock); delete(unsigned char *)Context; return DemultiplexorNoError; }
AllocatorStatus_t AllocatorSimple_c::LargestFreeBlock(unsigned int *Size) { int Index; OS_LockMutex(&Lock); Index = LargestFreeBlock(); *Size = (Index < 0) ? 0 : Blocks[Index].Size; OS_UnLockMutex(&Lock); return AllocatorNoError; }
RingStatus_t RingGeneric_c::Flush( void ) { OS_LockMutex( &Lock ); NextExtract = 0; NextInsert = 0; OS_UnLockMutex( &Lock ); return RingNoError; }
//}}} //{{{ AddStream //{{{ doxynote /// \brief Create a new stream, initialise it and add it to this playback /// \param Media Textual description of media (audio or video) /// \param Format Stream packet format (PES) /// \param Encoding The encoding of the stream content (MPEG2/H264 etc) /// \param SurfaceId Topological identifier for PiP and speaker-in-speaker. /// \param HavanaStream Reference to created stream /// \return Havana status code, HavanaNoError indicates success. //}}} HavanaStatus_t HavanaPlayback_c::AddStream (char* Media, char* Format, char* Encoding, unsigned int SurfaceId, class HavanaStream_c** HavanaStream) { HavanaStatus_t Status; int i; //if (*HavanaStream != NULL) // Device already has this stream // return HavanaStreamAlreadyExists; OS_LockMutex (&Lock); for (i = 0; i < MAX_STREAMS_PER_PLAYBACK; i++) { if (Stream[i] == NULL) break; } if (i == MAX_STREAMS_PER_PLAYBACK) { PLAYBACK_ERROR("Unable to create stream context - Too many streams\n"); OS_UnLockMutex (&Lock); return HavanaTooManyStreams; } Stream[i] = new HavanaStream_c(); if (Stream[i] == NULL) { PLAYBACK_ERROR("Unable to create stream context - insufficient memory\n"); OS_UnLockMutex (&Lock); return HavanaNoMemory; } Status = Stream[i]->Init (HavanaPlayer, Player, PlayerPlayback, Media, Format, Encoding, SurfaceId); if (Status != HavanaNoError) { delete Stream[i]; Stream[i] = NULL; OS_UnLockMutex (&Lock); return Status; } //PLAYBACK_DEBUG ("Adding stream %p, %d\n", Stream[i], i); *HavanaStream = Stream[i]; OS_UnLockMutex (&Lock); return HavanaNoError; }
void BufferManager_Generic_c::Dump(unsigned int Flags) { unsigned int i; BufferPool_Generic_t Pool; // if ((Flags & DumpBufferTypes) != 0) { report(severity_info, "Dump of Buffer Types\n"); for (i = 0; i < TypeDescriptorCount; i++) if ((TypeDescriptors[i].Type & TYPE_TYPE_MASK) == BufferDataTypeBase) { report(severity_info, " Buffer Type $%04x - '%s'\n", TypeDescriptors[i].Type, (TypeDescriptors[i].TypeName == NULL) ? "Unnamed" : TypeDescriptors[i].TypeName); report(severity_info, "\tAllocationSource = %s\n", (TypeDescriptors[i].AllocationSource <= AllocateIndividualSuppliedBlocks) ? AllocationSources[TypeDescriptors[i].AllocationSource] : "Invalid"); report(severity_info, "\tRequiredAllignment = %08x, AllocationUnitSize = %08x, AllocateOnPoolCreation = %d\n", TypeDescriptors[i].RequiredAllignment, TypeDescriptors[i].AllocationUnitSize, TypeDescriptors[i].AllocateOnPoolCreation); report(severity_info, "\tHasFixedSize = %d, FixedSize = %08x\n", TypeDescriptors[i].HasFixedSize, TypeDescriptors[i].FixedSize); } report(severity_info, "\n"); } // if ((Flags & DumpMetaDataTypes) != 0) { report(severity_info, "Dump of Meta Data Types\n"); for (i = 0; i < TypeDescriptorCount; i++) if ((TypeDescriptors[i].Type & TYPE_TYPE_MASK) == MetaDataTypeBase) { report(severity_info, " Buffer Type $%04x - '%s'\n", TypeDescriptors[i].Type, (TypeDescriptors[i].TypeName == NULL) ? "Unnamed" : TypeDescriptors[i].TypeName); report(severity_info, "\tAllocationSource = %s\n", (TypeDescriptors[i].AllocationSource <= AllocateIndividualSuppliedBlocks) ? AllocationSources[TypeDescriptors[i].AllocationSource] : "Invalid"); report(severity_info, "\tRequiredAllignment = %08x, AllocationUnitSize = %08x, AllocateOnPoolCreation = %d\n", TypeDescriptors[i].RequiredAllignment, TypeDescriptors[i].AllocationUnitSize, TypeDescriptors[i].AllocateOnPoolCreation); report(severity_info, "\tHasFixedSize = %d, FixedSize = %08x\n", TypeDescriptors[i].HasFixedSize, TypeDescriptors[i].FixedSize); } report(severity_info, "\n"); } // if ((Flags & DumpListPools) != 0) { report(severity_info, "Dump of Buffer Pools\n"); OS_LockMutex(&Lock); for (Pool = ListOfBufferPools; Pool != NULL; Pool = Pool->Next) { Pool->Dump(Flags); } OS_UnLockMutex(&Lock); } }
void gsiReleaseSemaphore(GSISemaphoreID theSemaphore, gsi_i32 theReleaseCount) { OS_LockMutex(&theSemaphore.mLock); theSemaphore.mValue += theReleaseCount; if(theSemaphore.mValue > theSemaphore.mMax) theSemaphore.mValue = theSemaphore.mMax; OS_UnlockMutex(&theSemaphore.mLock); }
//////////////////////////////////////////////////////////////////////////// /// /// Push a previously dequeued buffer back to the head of the buffer queue. /// /// Must be called only from the mixer playback thread. /// /// \param BufferIndex Index of the previously dequeued buffer. /// void Manifestor_Audio_c::PushBackBuffer(unsigned int BufferIndex) { OS_LockMutex(&BufferQueueLock); StreamBuffer[BufferIndex].NextIndex = BufferQueueHead; if (BufferQueueHead == INVALID_BUFFER_ID) BufferQueueTail = BufferIndex; BufferQueueHead = BufferIndex; QueuedBufferCount++; NotQueuedBufferCount--; OS_UnLockMutex(&BufferQueueLock); }
StackStatus_t StackGeneric_c::Push(unsigned int Value) { OS_LockMutex(&Lock); if (Level == Limit) { OS_UnLockMutex(&Lock); return StackTooManyEntries; } Storage[Level++] = Value; OS_UnLockMutex(&Lock); return StackNoError; }
/* * Send a command to V9t9 */ void GTK_send_command(const gchar *text) { GdkColor red = { 0, 0x8000, 0x0000, 0x0000 }; GTK_append_log(text, &red, NULL); GTK_append_log("\n", &red, NULL); OS_LockMutex(&command_mutex); command_exec_text((char *)text); OS_UnlockMutex(&command_mutex); }
//}}} //{{{ CreatePlayback HavanaStatus_t HavanaPlayer_c::CreatePlayback (HavanaPlayback_c** HavanaPlayback) { HavanaStatus_t HavanaStatus; int i; HAVANA_DEBUG("\n"); OS_LockMutex (&Lock); for (i = 0; i < MAX_PLAYBACKS; i++) { if (Playback[i] != NULL) { if (Playback[i]->Active () == HavanaPlaybackActive) continue; } break; } if (i == MAX_PLAYBACKS) { HAVANA_ERROR("Unable to create playback context - Too many playbacks\n"); OS_UnLockMutex (&Lock); return HavanaTooManyPlaybacks; } if (Playback[i] == NULL) Playback[i] = new HavanaPlayback_c (); if (Playback[i] == NULL) { HAVANA_ERROR("Unable to create playback context - insufficient memory\n"); OS_UnLockMutex (&Lock); return HavanaNoMemory; } HavanaStatus = Playback[i]->Init (this, Player, BufferManager); if (HavanaStatus != HavanaNoError) { HAVANA_ERROR("Unable to create playback context %x\n", HavanaStatus); delete Playback[i]; Playback[i] = NULL; OS_UnLockMutex (&Lock); return HavanaStatus; } *HavanaPlayback = Playback[i]; OS_UnLockMutex (&Lock); return HavanaNoError; }
StackStatus_t StackGeneric_c::Pop(unsigned int *Value) { // // If there is nothing in the Stack we return // if (Level != 0) { OS_LockMutex(&Lock); *Value = Storage[--Level]; OS_UnLockMutex(&Lock); return StackNoError; } return StackNothingToGet; }
ManifestorStatus_t Manifestor_Audio_c::DequeueBuffer(unsigned int *BufferIndexPtr, bool NonBlock) { unsigned int BufferIndex; while( !ForcedUnblock ) { // // Dequeue the buffer // OS_LockMutex(&BufferQueueLock); if( BufferQueueHead != INVALID_BUFFER_ID ) { #ifdef __TDT__ if(QueuedBufferCount < 3) inject_silent_count = 3; if(inject_silent_count > 0) { OS_UnLockMutex(&BufferQueueLock); inject_silent_count--; return ManifestorWouldBlock; } #endif BufferIndex = BufferQueueHead; BufferQueueHead = StreamBuffer[BufferIndex].NextIndex; QueuedBufferCount--; NotQueuedBufferCount++; OS_UnLockMutex(&BufferQueueLock); *BufferIndexPtr = BufferIndex; return ManifestorNoError; } OS_UnLockMutex(&BufferQueueLock); // // Block if no buffer is available. // if( NonBlock ) return ManifestorWouldBlock; OS_WaitForEvent(&BufferQueueUpdated, OS_INFINITE); OS_ResetEvent(&BufferQueueUpdated); } return ManifestorError; }
AllocatorStatus_t AllocatorSimple_c::Allocate( unsigned int Size, unsigned char **Block, bool NonBlocking) { unsigned int i; // if (this == NULL) return AllocatorError; // InAllocate = true; Size = (((Size + SegmentSize - 1) / SegmentSize) * SegmentSize); do { OS_LockMutex(&Lock); OS_ResetEvent(&EntryFreed); // if (BeingDeleted) break; // for (i = 0; i < (HighestUsedBlockIndex + 1); i++) if (Blocks[i].InUse && (Blocks[i].Size >= Size)) { *Block = Blocks[i].Base; Blocks[i].Base += Size; Blocks[i].Size -= Size; if (Blocks[i].Size == 0) Blocks[i].InUse = false; OS_UnLockMutex(&Lock); InAllocate = false; return AllocatorNoError; } // #if 0 { report(severity_info, "Waiting for memory \n"); for (i = 0; i < ALLOCATOR_SIMPLE_MAX_BLOCKS; i++) if (Blocks[i].InUse) report(severity_info, " %08x - %06x\n", Blocks[i].Base, Blocks[i].Size); } #endif // OS_UnLockMutex(&Lock); if (!NonBlocking) OS_WaitForEvent(&EntryFreed, OS_INFINITE); } while (!NonBlocking && !BeingDeleted); InAllocate = false; return AllocatorUnableToAllocate; }
BufferStatus_t Buffer_Generic_c::DecrementReferenceCount( unsigned int OldOwnerIdentifier ) { unsigned int i; unsigned int ReferenceCountAfterDecrement; // AssertNonZeroReferenceCount( "Buffer_Generic_c::DecrementReferenceCount" ); OS_LockMutex( &Pool->Lock ); Pool->ReferenceCount--; OS_UnLockMutex( &Pool->Lock ); OS_LockMutex( &Lock ); ReferenceCountAfterDecrement = --ReferenceCount; OS_UnLockMutex( &Lock ); if( OldOwnerIdentifier != UNSPECIFIED_OWNER ) { for( i=0; i<MAX_BUFFER_OWNER_IDENTIFIERS; i++ ) if( OwnerIdentifier[i] == OldOwnerIdentifier ) { OwnerIdentifier[i] = UNSPECIFIED_OWNER; break; } } // if( ReferenceCountAfterDecrement == 0 ) return Pool->ReleaseBuffer( this ); // return BufferNoError; }
OS_Status_t OS_WaitForEvent(OS_Event_t *Event, OS_Timeout_t Timeout) { if (!((*Event)->Valid)) { OS_LockMutex(&((*Event)->Mutex)); if (!((*Event)->Valid)) // NOTE this may have changed before we locked access { OS_UnLockMutex(&((*Event)->Mutex)); OSDEV_WaitForQueue((*Event)->Queue, &((*Event)->Valid), (Timeout == OS_INFINITE) ? OSDEV_INFINITE : Timeout); return ((*Event)->Valid) ? OS_NO_ERROR : OS_TIMED_OUT; } else OS_UnLockMutex(&((*Event)->Mutex)); } return OS_NO_ERROR; }
//{{{ CheckEvent HavanaStatus_t HavanaPlayback_c::CheckEvent(struct PlayerEventRecord_s* PlayerEvent) { int i; HavanaStatus_t HavanaStatus = HavanaError; OS_LockMutex(&Lock); // Make certain we cannot delete stream while checking the event for (i = 0; i < MAX_STREAMS_PER_PLAYBACK; i++) { if (Stream[i] != NULL) { HavanaStatus = Stream[i]->CheckEvent(PlayerEvent); if (HavanaStatus == HavanaNoError) break; } } OS_UnLockMutex(&Lock); return HavanaStatus; }
BufferStatus_t Buffer_Generic_c::DetachMetaData( MetaDataType_t Type ) { BlockDescriptor_t *LocationOfBlockPointer; BlockDescriptor_t Block; // // First find the descriptor block in the buffer // AssertNonZeroReferenceCount( "Buffer_Generic_c::DetachMetaData" ); OS_LockMutex( &Lock ); for( LocationOfBlockPointer = &ListOfMetaData; *LocationOfBlockPointer != NULL; LocationOfBlockPointer = &((*LocationOfBlockPointer)->Next) ) if( ((*LocationOfBlockPointer)->Descriptor->Type == Type) && !((*LocationOfBlockPointer)->AttachedToPool) ) break; if( *LocationOfBlockPointer == NULL ) { report( severity_error, "Buffer_Generic_c::DetachMetaData - No meta data of the specified type is attached to the buffer.\n" ); OS_UnLockMutex( &Lock ); return BufferMetaDataTypeNotFound; } // // Get a local block pointer, and unthread the block from the list // Block = *LocationOfBlockPointer; *LocationOfBlockPointer = Block->Next; // // Free up the memory, and delete the block record. // Pool->DeAllocateMemoryBlock( Block ); delete Block; // OS_UnLockMutex( &Lock ); return BufferNoError; }