From 072b9ed0ac55f928af26dcebabb3397b17c96617 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Sat, 23 Nov 2019 15:13:24 -0500 Subject: [PATCH] kernel/port: Properly release the first reference to the Port object. Creating a BReferenceable sets its reference count to 1. create_port() was then acquiring 2 references for the two lists it inserts the port object into, and subsequently delete_port() releases those. But that "reference 0" never was released anywhere, and so despite being removed from hashes, etc. port objects were just leaked, along with whatever messages remained in their queue, never to be freed. This of course can add up pretty quickly in systems that created and deleted ports frequently, for instance, in long-running media playback, opening/closing applications, etc. As far as I can tell, this bug was introduced in the fix to #8007 (7f64b301b1e78fb5a50c44a0cb2bb94a91e31d00), which introduced the ref-counting system to the port heap, so it has been with us since 2013 (!). Fixes #15489, and probably some of the other "media playback memory leak" tickets. --- src/system/kernel/port.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system/kernel/port.cpp b/src/system/kernel/port.cpp index 75240a4e8c..204934e13c 100644 --- a/src/system/kernel/port.cpp +++ b/src/system/kernel/port.cpp @@ -993,12 +993,12 @@ create_port(int32 queueLength, const char* name) name != NULL ? name : "unnamed port"); if (port == NULL) return B_NO_MEMORY; + BReference portRef(port, true); // check the ports limit const int32 previouslyUsed = atomic_add(&sUsedPorts, 1); if (previouslyUsed + 1 >= sMaxPorts) { atomic_add(&sUsedPorts, -1); - delete port; return B_NO_MORE_PORTS; }