[haiku-commits] haiku: hrev53379 - src/kits/media

  • From: waddlesplash <waddlesplash@xxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 15 Aug 2019 23:56:32 -0400 (EDT)

hrev53379 adds 1 changeset to branch 'master'
old head: 72b37d9ffc7e083a3f44ebf24e064596e0392b63
new head: fe08f0b3d0489bded18325689900a99dbad40694
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=fe08f0b3d048+%5E72b37d9ffc7e

----------------------------------------------------------------------------

fe08f0b3d048: Media Kit: Clear the BufferCache of buffers for disconnected 
clients
  
  Without this, the BufferCache keeps a reference to these buffers inside the
  media_addon_server until the media_addon_server quits, which is pretty much
  never.
  
  Should fix #4954 and #14755, and possibly #13614 and #14047, though I think
  they may be something else.
  
  Switched from std::map to our HashMap to get something which works in gcc2 and
  gcc8.
  
  Change-Id: I26463899724b9d1520d97fec785e435f536eaf3d
  Reviewed-on: https://review.haiku-os.org/c/haiku/+/1717
  Reviewed-by: waddlesplash <waddlesplash@xxxxxxxxx>

                                  [ Ryan Leavengood <leavengood@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev53379
Commit:      fe08f0b3d0489bded18325689900a99dbad40694
URL:         https://git.haiku-os.org/haiku/commit/?id=fe08f0b3d048
Author:      Ryan Leavengood <leavengood@xxxxxxxxx>
Date:        Wed Aug 14 21:59:01 2019 UTC
Committer:   waddlesplash <waddlesplash@xxxxxxxxx>
Commit-Date: Fri Aug 16 03:56:27 2019 UTC

Ticket:      https://dev.haiku-os.org/ticket/4954
Ticket:      https://dev.haiku-os.org/ticket/13614
Ticket:      https://dev.haiku-os.org/ticket/14047
Ticket:      https://dev.haiku-os.org/ticket/14755

----------------------------------------------------------------------------

3 files changed, 48 insertions(+), 15 deletions(-)
src/kits/media/BufferCache.cpp    | 40 ++++++++++++++++++++++++++---------
src/kits/media/BufferCache.h      | 16 ++++++++++----
src/kits/media/BufferConsumer.cpp |  7 +++++-

----------------------------------------------------------------------------

diff --git a/src/kits/media/BufferCache.cpp b/src/kits/media/BufferCache.cpp
index 9ebf9d6216..cbcc6ac7c7 100644
--- a/src/kits/media/BufferCache.cpp
+++ b/src/kits/media/BufferCache.cpp
@@ -1,4 +1,5 @@
 /*
+ * Copyright 2019, Ryan Leavengood.
  * Copyright 2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
  * Copyright 2002, Marcus Overhagen. All Rights Reserved.
  * Distributed under the terms of the MIT License.
@@ -25,22 +26,23 @@ BufferCache::BufferCache()
 
 BufferCache::~BufferCache()
 {
-       for (BufferMap::iterator iterator = fMap.begin(); iterator != 
fMap.end();
-                       iterator++) {
-               delete iterator->second;
+       BufferMap::Iterator iterator = fMap.GetIterator();
+       while (iterator.HasNext()) {
+               BufferMap::Entry entry = iterator.Next();
+               delete entry.value.buffer;
        }
 }
 
 
 BBuffer*
-BufferCache::GetBuffer(media_buffer_id id)
+BufferCache::GetBuffer(media_buffer_id id, port_id port)
 {
        if (id <= 0)
                return NULL;
 
-       BufferMap::iterator found = fMap.find(id);
-       if (found != fMap.end())
-               return found->second;
+       buffer_cache_entry* existing;
+       if (fMap.Get(id, existing))
+               return existing->buffer;
 
        buffer_clone_info info;
        info.buffer = id;
@@ -54,9 +56,11 @@ BufferCache::GetBuffer(media_buffer_id id)
        if (buffer->ID() != id)
                debugger("BufferCache::GetBuffer: IDs mismatch");
 
-       try {
-               fMap.insert(std::make_pair(id, buffer));
-       } catch (std::bad_alloc& exception) {
+       buffer_cache_entry entry;
+       entry.buffer = buffer;
+       entry.port = port;
+       status_t error = fMap.Put(id, entry);
+       if (error != B_OK) {
                delete buffer;
                return NULL;
        }
@@ -65,4 +69,20 @@ BufferCache::GetBuffer(media_buffer_id id)
 }
 
 
+void
+BufferCache::FlushCacheForPort(port_id port)
+{
+       BufferMap::Iterator iterator = fMap.GetIterator();
+       while (iterator.HasNext()) {
+               BufferMap::Entry entry = iterator.Next();
+               if (entry.value.port == port) {
+                       // Delete the buffer
+                       delete entry.value.buffer;
+                       // Then remove it from the map
+                       fMap.Remove(iterator);
+               }
+       }
+}
+
+
 }      // namespace BPrivate
diff --git a/src/kits/media/BufferCache.h b/src/kits/media/BufferCache.h
index 228b52991a..65e4babde5 100644
--- a/src/kits/media/BufferCache.h
+++ b/src/kits/media/BufferCache.h
@@ -1,4 +1,5 @@
 /*
+ * Copyright 2019, Ryan Leavengood.
  * Copyright 2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx.
  * Copyright 2002, Marcus Overhagen. All Rights Reserved.
  * Distributed under the terms of the MIT License.
@@ -7,8 +8,7 @@
 #define _BUFFER_CACHE_H_
 
 
-#include <map>
-
+#include <HashMap.h>
 #include <MediaDefs.h>
 
 
@@ -18,15 +18,23 @@ class BBuffer;
 namespace BPrivate {
 
 
+struct buffer_cache_entry {
+       BBuffer*        buffer;
+       port_id         port;
+};
+
+
 class BufferCache {
 public:
                                                                BufferCache();
                                                                ~BufferCache();
 
-                       BBuffer*                        
GetBuffer(media_buffer_id id);
+                       BBuffer*                        
GetBuffer(media_buffer_id id, port_id port);
+
+                       void                            
FlushCacheForPort(port_id port);
 
 private:
-       typedef std::map<media_buffer_id, BBuffer*> BufferMap;
+       typedef HashMap<HashKey32<media_buffer_id>, buffer_cache_entry> 
BufferMap;
 
                        BufferMap                       fMap;
 };
diff --git a/src/kits/media/BufferConsumer.cpp 
b/src/kits/media/BufferConsumer.cpp
index 73c0626194..277adcb55d 100644
--- a/src/kits/media/BufferConsumer.cpp
+++ b/src/kits/media/BufferConsumer.cpp
@@ -379,7 +379,8 @@ BBufferConsumer::HandleMessage(int32 message, const void* 
data, size_t size)
                        const consumer_buffer_received_command* command
                                = static_cast<const 
consumer_buffer_received_command*>(data);
 
-                       BBuffer* buffer = 
fBufferCache->GetBuffer(command->buffer);
+                       BBuffer* buffer = 
fBufferCache->GetBuffer(command->buffer,
+                               command->header.source_port);
                        if (buffer == NULL) {
                                
ERROR("BBufferConsumer::CONSUMER_BUFFER_RECEIVED can't"
                                        "find the buffer\n");
@@ -425,6 +426,10 @@ BBufferConsumer::HandleMessage(int32 message, const void* 
data, size_t size)
                case CONSUMER_DISCONNECTED:
                {
                        const consumer_disconnected_request *request = 
static_cast<const consumer_disconnected_request *>(data);
+                       // We no longer need to cache the buffers requested by 
the other end
+                       // of this port.
+                       fBufferCache->FlushCacheForPort(request->source.port);
+
                        consumer_disconnected_reply reply;
                        Disconnected(request->source, request->destination);
                        request->SendReply(B_OK, &reply, sizeof(reply));


Other related posts: