19dec2310SAxel Dörfler /* 2fe08f0b3SRyan Leavengood * Copyright 2019, Ryan Leavengood. 39dec2310SAxel Dörfler * Copyright 2009, Axel Dörfler, axeld@pinc-software.de. 49dec2310SAxel Dörfler * Copyright 2002, Marcus Overhagen. All Rights Reserved. 59dec2310SAxel Dörfler * Distributed under the terms of the MIT License. 69dec2310SAxel Dörfler */ 79dec2310SAxel Dörfler 89dec2310SAxel Dörfler 99dec2310SAxel Dörfler //! A cache for BBuffers to be received by BBufferConsumer::BufferReceived(). 109dec2310SAxel Dörfler 119dec2310SAxel Dörfler 129dec2310SAxel Dörfler #include "BufferCache.h" 139dec2310SAxel Dörfler 149dec2310SAxel Dörfler #include <Buffer.h> 159dec2310SAxel Dörfler 16b84955d4SBarrett17 #include "MediaDebug.h" 17*9c9a810cSJérôme Duval #include "MediaMisc.h" 18*9c9a810cSJérôme Duval #include "SharedBufferList.h" 199dec2310SAxel Dörfler 209dec2310SAxel Dörfler 219dec2310SAxel Dörfler namespace BPrivate { 229dec2310SAxel Dörfler 239dec2310SAxel Dörfler BufferCache()249dec2310SAxel DörflerBufferCache::BufferCache() 259dec2310SAxel Dörfler { 269dec2310SAxel Dörfler } 279dec2310SAxel Dörfler 289dec2310SAxel Dörfler ~BufferCache()299dec2310SAxel DörflerBufferCache::~BufferCache() 309dec2310SAxel Dörfler { 31fe08f0b3SRyan Leavengood BufferMap::Iterator iterator = fMap.GetIterator(); 32fe08f0b3SRyan Leavengood while (iterator.HasNext()) { 33fe08f0b3SRyan Leavengood BufferMap::Entry entry = iterator.Next(); 34fe08f0b3SRyan Leavengood delete entry.value.buffer; 359dec2310SAxel Dörfler } 369dec2310SAxel Dörfler } 379dec2310SAxel Dörfler 389dec2310SAxel Dörfler 399dec2310SAxel Dörfler BBuffer* GetBuffer(media_buffer_id id,port_id port)40fe08f0b3SRyan LeavengoodBufferCache::GetBuffer(media_buffer_id id, port_id port) 419dec2310SAxel Dörfler { 42aa50bf9eSDario Casalinuovo if (id <= 0) 43aa50bf9eSDario Casalinuovo return NULL; 44aa50bf9eSDario Casalinuovo 45fe08f0b3SRyan Leavengood buffer_cache_entry* existing; 46*9c9a810cSJérôme Duval if (fMap.Get(id, existing)) { 47*9c9a810cSJérôme Duval existing->buffer->fFlags |= BUFFER_TO_RECLAIM; 48fe08f0b3SRyan Leavengood return existing->buffer; 49*9c9a810cSJérôme Duval } 509dec2310SAxel Dörfler 519dec2310SAxel Dörfler buffer_clone_info info; 529dec2310SAxel Dörfler info.buffer = id; 539dec2310SAxel Dörfler BBuffer* buffer = new(std::nothrow) BBuffer(info); 54d98b8c7cSDario Casalinuovo if (buffer == NULL || buffer->ID() <= 0 55d98b8c7cSDario Casalinuovo || buffer->Data() == NULL) { 56384ae40aSDario Casalinuovo delete buffer; 579dec2310SAxel Dörfler return NULL; 58384ae40aSDario Casalinuovo } 599dec2310SAxel Dörfler 60d98b8c7cSDario Casalinuovo if (buffer->ID() != id) 61d98b8c7cSDario Casalinuovo debugger("BufferCache::GetBuffer: IDs mismatch"); 62d98b8c7cSDario Casalinuovo 63fe08f0b3SRyan Leavengood buffer_cache_entry entry; 64fe08f0b3SRyan Leavengood entry.buffer = buffer; 65fe08f0b3SRyan Leavengood entry.port = port; 66fe08f0b3SRyan Leavengood status_t error = fMap.Put(id, entry); 67fe08f0b3SRyan Leavengood if (error != B_OK) { 689dec2310SAxel Dörfler delete buffer; 699dec2310SAxel Dörfler return NULL; 709dec2310SAxel Dörfler } 719dec2310SAxel Dörfler 72*9c9a810cSJérôme Duval buffer->fFlags |= BUFFER_TO_RECLAIM; 739dec2310SAxel Dörfler return buffer; 749dec2310SAxel Dörfler } 759dec2310SAxel Dörfler 769dec2310SAxel Dörfler 77fe08f0b3SRyan Leavengood void FlushCacheForPort(port_id port)78fe08f0b3SRyan LeavengoodBufferCache::FlushCacheForPort(port_id port) 79fe08f0b3SRyan Leavengood { 80fe08f0b3SRyan Leavengood BufferMap::Iterator iterator = fMap.GetIterator(); 81fe08f0b3SRyan Leavengood while (iterator.HasNext()) { 82fe08f0b3SRyan Leavengood BufferMap::Entry entry = iterator.Next(); 83fe08f0b3SRyan Leavengood if (entry.value.port == port) { 84*9c9a810cSJérôme Duval BBuffer* buffer = entry.value.buffer; 85*9c9a810cSJérôme Duval bool isReclaimed = (buffer->fFlags & BUFFER_TO_RECLAIM) == 0; 86*9c9a810cSJérôme Duval if (isReclaimed && buffer->fBufferList != NULL) 87*9c9a810cSJérôme Duval isReclaimed = buffer->fBufferList->RemoveBuffer(buffer) == B_OK; 88*9c9a810cSJérôme Duval 89*9c9a810cSJérôme Duval if (isReclaimed) 90*9c9a810cSJérôme Duval delete buffer; 91*9c9a810cSJérôme Duval else { 92*9c9a810cSJérôme Duval // mark the buffer for deletion 93*9c9a810cSJérôme Duval buffer->fFlags |= BUFFER_MARKED_FOR_DELETION; 94*9c9a810cSJérôme Duval } 95fe08f0b3SRyan Leavengood // Then remove it from the map 96fe08f0b3SRyan Leavengood fMap.Remove(iterator); 97fe08f0b3SRyan Leavengood } 98fe08f0b3SRyan Leavengood } 99fe08f0b3SRyan Leavengood } 100fe08f0b3SRyan Leavengood 101fe08f0b3SRyan Leavengood 1029dec2310SAxel Dörfler } // namespace BPrivate 103