Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fix several memory leaks #1946

Merged
merged 7 commits into from

3 participants

Jim Carroll davilla rbej
Jim Carroll
Collaborator

This addresses several memory leaks that I found trying to track down why the RPi runs out of memory after playing a few videos.

davilla
Collaborator

if you feel confident, inject

Jim Carroll jimfcarroll merged commit b5480d6 into from
rbej

Still memory leak when playing online movies. Only solution is set unlimited cache buffer in advenced settings and write cache on sd card. When i downgrade kernel to 3.2 everything is perfect.

https://dl.dropbox.com/u/94360623/xbmc%20log%20testing/xbmc.log

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 17, 2012
  1. [fix] memory leak in AudioEngine.

    Jim Carroll authored
  2. [fix] leak in LircButtonMapEntries.

    Jim Carroll authored
  3. [fix] partial fix for leaks of JSONRPC meta-data. There are circular …

    Jim Carroll authored
    …shared_ptr references that need to be sorted out before this will work properly.
  4. added a number of the settings collections to be cleared in the Clear…

    Jim Carroll authored
    … method for better memory management.
  5. [fix] use the cleanup code that was added in the previous fix from th…

    Jim Carroll authored
    …e CApplication shutdown.
This page is out of date. Refresh to see the latest.
8 xbmc/Application.cpp
View
@@ -2075,6 +2075,8 @@ void CApplication::UnloadSkin(bool forReload /* = false */)
g_charsetConverter.reset();
g_infoManager.Clear();
+
+ g_SkinInfo.reset();
}
bool CApplication::LoadUserWindows()
@@ -3456,7 +3458,11 @@ bool CApplication::Cleanup()
#ifdef _LINUX
CXHandle::DumpObjectTracker();
+
+#ifdef HAS_DVD_DRIVE
+ CLibcdio::ReleaseInstance();
#endif
+#endif
#if defined(TARGET_ANDROID)
// enable for all platforms once it's safe
g_sectionLoader.UnloadAll();
@@ -3527,6 +3533,7 @@ void CApplication::Stop(int exitCode)
CWebServer::UnregisterRequestHandler(&m_httpVfsHandler);
#ifdef HAS_JSONRPC
CWebServer::UnregisterRequestHandler(&m_httpJsonRpcHandler);
+ CJSONRPC::Cleanup();
#endif
#ifdef HAS_WEB_INTERFACE
CWebServer::UnregisterRequestHandler(&m_httpWebinterfaceAddonsHandler);
@@ -3605,6 +3612,7 @@ void CApplication::Stop(int exitCode)
// shutdown the AudioEngine
CAEFactory::Shutdown();
+ CAEFactory::UnLoadEngine();
CLog::Log(LOGNOTICE, "stopped");
}
2  xbmc/cores/AudioEngine/Engines/SoftAE/SoftAE.cpp
View
@@ -663,6 +663,8 @@ void CSoftAE::Deinitialize()
_aligned_free(m_converted);
m_converted = NULL;
m_convertedSize = 0;
+
+ m_sinkInfoList.clear();
}
void CSoftAE::EnumerateOutputDevices(AEDeviceList &devices, bool passthrough)
3  xbmc/cores/AudioEngine/Engines/SoftAE/SoftAEStream.cpp
View
@@ -226,6 +226,9 @@ CSoftAEStream::~CSoftAEStream()
m_ssrc = NULL;
}
+ delete m_newPacket;
+ delete m_packet;
+
CLog::Log(LOGDEBUG, "CSoftAEStream::~CSoftAEStream - Destructed");
}
2  xbmc/filesystem/CDDAFile.h
View
@@ -53,7 +53,7 @@ class CFileCDDA : public IFile
lsn_t m_lsnStart; // Start of m_iTrack in logical sector number
lsn_t m_lsnCurrent; // Position inside the track in logical sector number
lsn_t m_lsnEnd; // End of m_iTrack in logical sector number
- MEDIA_DETECT::CLibcdio* m_cdio;
+ boost::shared_ptr<MEDIA_DETECT::CLibcdio> m_cdio;
};
}
5 xbmc/guilib/Tween.h
View
@@ -61,16 +61,13 @@ enum TweenerType
class Tweener
{
public:
- Tweener(TweenerType tweenerType = EASE_OUT) { m_tweenerType = tweenerType; _ref=1; }
+ Tweener(TweenerType tweenerType = EASE_OUT) { m_tweenerType = tweenerType; }
virtual ~Tweener() {};
void SetEasing(TweenerType type) { m_tweenerType = type; }
virtual float Tween(float time, float start, float change, float duration)=0;
- void Free() { _ref--; if (_ref==0) delete this; }
- void IncRef() { _ref++; }
virtual bool HasResumePoint() const { return m_tweenerType == EASE_INOUT; }
protected:
- int _ref;
TweenerType m_tweenerType;
};
46 xbmc/guilib/VisibleEffect.cpp
View
@@ -33,7 +33,7 @@ CAnimEffect::CAnimEffect(const TiXmlElement *node, EFFECT_TYPE effect)
m_effect = effect;
// defaults
m_delay = m_length = 0;
- m_pTweener = NULL;
+ m_pTweener.reset();
// time and delay
float temp;
@@ -48,18 +48,16 @@ CAnimEffect::CAnimEffect(unsigned int delay, unsigned int length, EFFECT_TYPE ef
m_delay = delay;
m_length = length;
m_effect = effect;
- m_pTweener = new LinearTweener();
+ m_pTweener = boost::shared_ptr<Tweener>(new LinearTweener());
}
CAnimEffect::~CAnimEffect()
{
- if (m_pTweener)
- m_pTweener->Free();
}
CAnimEffect::CAnimEffect(const CAnimEffect &src)
{
- m_pTweener = NULL;
+ m_pTweener.reset();
*this = src;
}
@@ -72,11 +70,7 @@ const CAnimEffect &CAnimEffect::operator=(const CAnimEffect &src)
m_length = src.m_length;
m_delay = src.m_delay;
- if (m_pTweener)
- m_pTweener->Free();
m_pTweener = src.m_pTweener;
- if (m_pTweener)
- m_pTweener->IncRef();
return *this;
}
@@ -101,28 +95,28 @@ void CAnimEffect::ApplyState(ANIMATION_STATE state, const CPoint &center)
ApplyEffect(offset, center);
}
-Tweener* CAnimEffect::GetTweener(const TiXmlElement *pAnimationNode)
+boost::shared_ptr<Tweener> CAnimEffect::GetTweener(const TiXmlElement *pAnimationNode)
{
- Tweener* m_pTweener = NULL;
+ boost::shared_ptr<Tweener> m_pTweener;
const char *tween = pAnimationNode->Attribute("tween");
if (tween)
{
if (strcmpi(tween, "linear")==0)
- m_pTweener = new LinearTweener();
+ m_pTweener = boost::shared_ptr<Tweener>(new LinearTweener());
else if (strcmpi(tween, "quadratic")==0)
- m_pTweener = new QuadTweener();
+ m_pTweener = boost::shared_ptr<Tweener>(new QuadTweener());
else if (strcmpi(tween, "cubic")==0)
- m_pTweener = new CubicTweener();
+ m_pTweener = boost::shared_ptr<Tweener>(new CubicTweener());
else if (strcmpi(tween, "sine")==0)
- m_pTweener = new SineTweener();
+ m_pTweener = boost::shared_ptr<Tweener>(new SineTweener());
else if (strcmpi(tween, "back")==0)
- m_pTweener = new BackTweener();
+ m_pTweener = boost::shared_ptr<Tweener>(new BackTweener());
else if (strcmpi(tween, "circle")==0)
- m_pTweener = new CircleTweener();
+ m_pTweener = boost::shared_ptr<Tweener>(new CircleTweener());
else if (strcmpi(tween, "bounce")==0)
- m_pTweener = new BounceTweener();
+ m_pTweener = boost::shared_ptr<Tweener>(new BounceTweener());
else if (strcmpi(tween, "elastic")==0)
- m_pTweener = new ElasticTweener();
+ m_pTweener = boost::shared_ptr<Tweener>(new ElasticTweener());
const char *easing = pAnimationNode->Attribute("easing");
if (m_pTweener && easing)
@@ -144,11 +138,11 @@ Tweener* CAnimEffect::GetTweener(const TiXmlElement *pAnimationNode)
// or quadratic if we have acceleration
if (accel)
{
- m_pTweener = new QuadTweener(accel);
+ m_pTweener = boost::shared_ptr<Tweener>(new QuadTweener(accel));
m_pTweener->SetEasing(EASE_IN);
}
else
- m_pTweener = new LinearTweener();
+ m_pTweener = boost::shared_ptr<Tweener>(new LinearTweener());
}
return m_pTweener;
@@ -709,7 +703,7 @@ void CAnimation::AddEffect(CAnimEffect *effect)
m_length = effect->GetLength() - m_delay;
}
-CScroller::CScroller(unsigned int duration /* = 200 */, Tweener *tweener /* = NULL */)
+CScroller::CScroller(unsigned int duration /* = 200 */, boost::shared_ptr<Tweener> tweener /* = NULL */)
{
m_scrollValue = 0;
m_delta = 0;
@@ -719,12 +713,11 @@ CScroller::CScroller(unsigned int duration /* = 200 */, Tweener *tweener /* = NU
m_lastTime = 0;
m_duration = duration > 0 ? duration : 1;
m_pTweener = tweener;
- if (m_pTweener) m_pTweener->IncRef();
}
CScroller::CScroller(const CScroller& right)
{
- m_pTweener = NULL;
+ m_pTweener.reset();
*this = right;
}
@@ -739,17 +732,12 @@ const CScroller &CScroller::operator=(const CScroller &right)
m_hasResumePoint = right.m_hasResumePoint;
m_lastTime = right.m_lastTime;
m_duration = right.m_duration;
- if (m_pTweener)
- m_pTweener->Free();
m_pTweener = right.m_pTweener;
- if (m_pTweener)
- m_pTweener->IncRef();
return *this;
}
CScroller::~CScroller()
{
- if (m_pTweener) m_pTweener->Free();
}
void CScroller::ScrollTo(float endPos)
9 xbmc/guilib/VisibleEffect.h
View
@@ -32,6 +32,7 @@ class CGUIListItem;
#include "TransformMatrix.h" // needed for the TransformMatrix member
#include "Geometry.h" // for CPoint, CRect
#include "utils/StdString.h"
+#include "boost/shared_ptr.hpp"
enum ANIMATION_TYPE
{
@@ -65,7 +66,7 @@ class CAnimEffect
const TransformMatrix &GetTransform() const { return m_matrix; };
EFFECT_TYPE GetType() const { return m_effect; };
- static Tweener* GetTweener(const TiXmlElement *pAnimationNode);
+ static boost::shared_ptr<Tweener> GetTweener(const TiXmlElement *pAnimationNode);
protected:
TransformMatrix m_matrix;
EFFECT_TYPE m_effect;
@@ -77,7 +78,7 @@ class CAnimEffect
unsigned int m_length;
unsigned int m_delay;
- Tweener *m_pTweener;
+ boost::shared_ptr<Tweener> m_pTweener;
};
class CFadeEffect : public CAnimEffect
@@ -213,7 +214,7 @@ class CAnimation
class CScroller
{
public:
- CScroller(unsigned int duration = 200, Tweener *tweener = NULL);
+ CScroller(unsigned int duration = 200, boost::shared_ptr<Tweener> tweener = boost::shared_ptr<Tweener>());
CScroller(const CScroller& right);
const CScroller &operator=(const CScroller &src);
~CScroller();
@@ -257,5 +258,5 @@ class CScroller
unsigned int m_lastTime; //!< Brief last remember time (updated each time Scroll() method is called)
unsigned int m_duration; //!< Brief duration of scroll
- Tweener* m_pTweener;
+ boost::shared_ptr<Tweener> m_pTweener;
};
12 xbmc/input/ButtonTranslator.cpp
View
@@ -413,9 +413,9 @@ CButtonTranslator::CButtonTranslator()
m_Loaded = false;
}
-CButtonTranslator::~CButtonTranslator()
-{
#if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
+void CButtonTranslator::ClearLircButtonMapEntries()
+{
vector<lircButtonMap*> maps;
for (map<CStdString,lircButtonMap*>::iterator it = lircRemotesMap.begin();
it != lircRemotesMap.end();++it)
@@ -424,6 +424,13 @@ CButtonTranslator::~CButtonTranslator()
vector<lircButtonMap*>::iterator itend = unique(maps.begin(),maps.end());
for (vector<lircButtonMap*>::iterator it = maps.begin(); it != itend;++it)
delete *it;
+}
+#endif
+
+CButtonTranslator::~CButtonTranslator()
+{
+#if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
+ ClearLircButtonMapEntries();
#endif
}
@@ -1333,6 +1340,7 @@ void CButtonTranslator::Clear()
{
m_translatorMap.clear();
#if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
+ ClearLircButtonMapEntries();
lircRemotesMap.clear();
#endif
3  xbmc/input/ButtonTranslator.h
View
@@ -129,7 +129,10 @@ class CButtonTranslator
bool LoadKeymap(const CStdString &keymapPath);
#if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
bool LoadLircMap(const CStdString &lircmapPath);
+ void ClearLircButtonMapEntries();
+
void MapRemote(TiXmlNode *pRemote, const char* szDevice);
+
typedef std::map<CStdString, CStdString> lircButtonMap;
std::map<CStdString, lircButtonMap*> lircRemotesMap;
#endif
6 xbmc/interfaces/json-rpc/JSONRPC.cpp
View
@@ -102,6 +102,12 @@ void CJSONRPC::Initialize()
CLog::Log(LOGINFO, "JSONRPC v%s: Successfully initialized", CJSONServiceDescription::GetVersion());
}
+void CJSONRPC::Cleanup()
+{
+ CJSONServiceDescription::Cleanup();
+ m_initialized = false;
+}
+
JSONRPC_STATUS CJSONRPC::Introspect(const CStdString &method, ITransportLayer *transport, IClient *client, const CVariant& parameterObject, CVariant &result)
{
return CJSONServiceDescription::Print(result, transport, client,
2  xbmc/interfaces/json-rpc/JSONRPC.h
View
@@ -47,6 +47,8 @@ namespace JSONRPC
*/
static void Initialize();
+ static void Cleanup();
+
/*
\brief Handles an incoming JSON-RPC request
\param inputString received JSON-RPC request
14 xbmc/interfaces/json-rpc/JSONServiceDescription.cpp
View
@@ -1332,6 +1332,15 @@ JSONRPC_STATUS JsonRpcMethod::checkParameter(const CVariant &requestParameters,
return OK;
}
+void CJSONServiceDescription::Cleanup()
+{
+ // reset all of the static data
+ m_notifications.clear();
+ m_actionMap.clear();
+ m_types.clear();
+ m_incompleteDefinitions.clear();
+}
+
bool CJSONServiceDescription::prepareDescription(std::string &description, CVariant &descriptionObject, std::string &name)
{
if (description.empty())
@@ -1966,6 +1975,11 @@ CJSONServiceDescription::CJsonRpcMethodMap::CJsonRpcMethodMap()
m_actionmap = std::map<std::string, JsonRpcMethod>();
}
+void CJSONServiceDescription::CJsonRpcMethodMap::clear()
+{
+ m_actionmap.clear();
+}
+
void CJSONServiceDescription::CJsonRpcMethodMap::add(const JsonRpcMethod &method)
{
CStdString name = method.name;
4 xbmc/interfaces/json-rpc/JSONServiceDescription.h
View
@@ -392,6 +392,8 @@ namespace JSONRPC
static JSONSchemaTypeDefinitionPtr GetType(const std::string &identification);
+ static void Cleanup();
+
private:
static bool prepareDescription(std::string &description, CVariant &descriptionObject, std::string &name);
static bool addMethod(const std::string &jsonMethod, MethodCall method);
@@ -413,6 +415,8 @@ namespace JSONRPC
JsonRpcMethodIterator begin() const;
JsonRpcMethodIterator find(const std::string& key) const;
JsonRpcMethodIterator end() const;
+
+ void clear();
private:
std::map<std::string, JsonRpcMethod> m_actionmap;
};
33 xbmc/settings/Settings.cpp
View
@@ -138,7 +138,7 @@ void CSettings::Initialize()
CSettings::~CSettings(void)
{
- m_ResInfo.clear();
+ Clear();
}
@@ -1473,16 +1473,37 @@ void CSettings::SaveSkinSettings(TiXmlNode *pRootElement) const
void CSettings::Clear()
{
+ m_vecProfiles.clear();
+
+ m_pictureExtensions.clear();
+ m_musicExtensions.clear();
+ m_videoExtensions.clear();
+ m_discStubExtensions.clear();
+
+ m_logFolder.clear();
+ m_userAgent.clear();
+
+ m_mapRssUrls.clear();
+ m_skinStrings.clear();
+ m_skinBools.clear();
+
m_programSources.clear();
m_pictureSources.clear();
m_fileSources.clear();
m_musicSources.clear();
m_videoSources.clear();
-// m_vecIcons.clear();
- m_vecProfiles.clear();
- m_mapRssUrls.clear();
- m_skinBools.clear();
- m_skinStrings.clear();
+
+ m_defaultProgramSource.clear();
+ m_defaultMusicSource.clear();
+ m_defaultPictureSource.clear();
+ m_defaultFileSource.clear();
+ m_defaultMusicLibSource.clear();
+
+ m_UPnPUUIDServer.clear();
+ m_UPnPUUIDRenderer.clear();
+
+ m_ResInfo.clear();
+ m_Calibrations.clear();
}
int CSettings::TranslateSkinString(const CStdString &setting)
3  xbmc/storage/DetectDVDType.h
View
@@ -36,6 +36,7 @@
#include "threads/Thread.h"
#include "utils/StdString.h"
+#include "boost/shared_ptr.hpp"
namespace MEDIA_DETECT
{
@@ -88,7 +89,7 @@ class CDetectDVDMedia : public CThread
static CStdString m_diskLabel;
static CStdString m_diskPath;
- CLibcdio* m_cdio;
+ boost::shared_ptr<CLibcdio> m_cdio;
};
}
#endif
2  xbmc/storage/MediaManager.cpp
View
@@ -638,7 +638,7 @@ void CMediaManager::EjectTray( const bool bEject, const char cDriveLetter )
#ifdef TARGET_WINDOWS
CWIN32Util::EjectTray(cDriveLetter);
#else
- CLibcdio *c_cdio = CLibcdio::GetInstance();
+ boost::shared_ptr<CLibcdio> c_cdio = CLibcdio::GetInstance();
char* dvdDevice = c_cdio->GetDeviceFileName();
m_isoReader.Reset();
int nRetries=3;
17 xbmc/storage/cdioSupport.cpp
View
@@ -36,8 +36,7 @@
using namespace MEDIA_DETECT;
-CLibcdio* CLibcdio::m_pInstance = NULL;
-char *CLibcdio::s_defaultDevice = NULL;
+boost::shared_ptr<CLibcdio> CLibcdio::m_pInstance;
/* Some interesting sector numbers stored in the above buffer. */
#define ISO_SUPERBLOCK_SECTOR 16 /* buffer[0] */
@@ -102,7 +101,7 @@ xbox_cdio_log_handler (cdio_log_level_t level, const char message[])
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-CLibcdio::CLibcdio()
+CLibcdio::CLibcdio(): s_defaultDevice(NULL)
{
cdio_log_set_handler( xbox_cdio_log_handler );
}
@@ -113,20 +112,16 @@ CLibcdio::~CLibcdio()
s_defaultDevice = NULL;
}
-void CLibcdio::RemoveInstance()
+void CLibcdio::ReleaseInstance()
{
- if (m_pInstance)
- {
- delete m_pInstance;
- m_pInstance = NULL;
- }
+ m_pInstance.reset();
}
-CLibcdio* CLibcdio::GetInstance()
+boost::shared_ptr<CLibcdio> CLibcdio::GetInstance()
{
if (!m_pInstance)
{
- m_pInstance = new CLibcdio();
+ m_pInstance = boost::shared_ptr<CLibcdio>(new CLibcdio());
}
return m_pInstance;
}
11 xbmc/storage/cdioSupport.h
View
@@ -37,6 +37,7 @@
#include <cdio/cdio.h>
#include "threads/CriticalSection.h"
#include "utils/StdString.h"
+#include "boost/shared_ptr.hpp"
#include <map>
namespace MEDIA_DETECT
@@ -257,8 +258,8 @@ class CLibcdio : public CCriticalSection
public:
virtual ~CLibcdio();
- static void RemoveInstance();
- static CLibcdio* GetInstance();
+ static void ReleaseInstance();
+ static boost::shared_ptr<CLibcdio> GetInstance();
// libcdio is not thread safe so these are wrappers to libcdio routines
CdIo_t* cdio_open(const char *psz_source, driver_id_t driver_id);
@@ -275,9 +276,9 @@ class CLibcdio : public CCriticalSection
char* GetDeviceFileName();
private:
- static char* s_defaultDevice;
+ char* s_defaultDevice;
CCriticalSection m_critSection;
- static CLibcdio* m_pInstance;
+ static boost::shared_ptr<CLibcdio> m_pInstance;
};
class CCdIoSupport
@@ -340,7 +341,7 @@ class CCdIoSupport
int m_nFirstAudio; /* # of first audio track */
int m_nNumAudio; /* # of audio tracks */
- CLibcdio* m_cdio;
+ boost::shared_ptr<CLibcdio> m_cdio;
};
}
Something went wrong with that request. Please try again.