aboutsummaryrefslogtreecommitdiff
path: root/src/adlmidi_private.hpp
diff options
context:
space:
mode:
authorVitaly Novichkov <Wohlstand@users.noreply.github.com>2018-04-10 10:32:57 +0300
committerGitHub <noreply@github.com>2018-04-10 10:32:57 +0300
commit7ee2255ba11cad215a255a709795443e731679d3 (patch)
tree03441e9a6cf8720a9b6227aa7f86a8fff0dc6515 /src/adlmidi_private.hpp
parentcd09e3835c59ffdaeec9666d0ee0cddea98772bf (diff)
parentb19f4b551ee6ea0d74e29af6c219788b65fc2ecd (diff)
downloadlibADLMIDI-7ee2255ba11cad215a255a709795443e731679d3.tar.gz
libADLMIDI-7ee2255ba11cad215a255a709795443e731679d3.tar.bz2
libADLMIDI-7ee2255ba11cad215a255a709795443e731679d3.zip
Merge pull request #52 from jpcima/fix-memory-problems
fix memory management issues
Diffstat (limited to 'src/adlmidi_private.hpp')
-rw-r--r--src/adlmidi_private.hpp81
1 files changed, 77 insertions, 4 deletions
diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp
index 4f727e2..395b7f7 100644
--- a/src/adlmidi_private.hpp
+++ b/src/adlmidi_private.hpp
@@ -143,9 +143,11 @@ public:
void reset(PTR *p = NULL)
{
- if(m_p)
- free(m_p);
- m_p = p;
+ if(p != m_p) {
+ if(m_p)
+ free(m_p);
+ m_p = p;
+ }
}
PTR *get()
@@ -160,6 +162,77 @@ public:
{
return m_p;
}
+private:
+ AdlMIDI_CPtr(const AdlMIDI_CPtr &);
+ AdlMIDI_CPtr &operator=(const AdlMIDI_CPtr &);
+};
+
+/*
+ Shared pointer with non-atomic counter
+ FAQ: Why not std::shared_ptr? Because of Android NDK now doesn't supports it
+*/
+template<class VALUE>
+class AdlMIDI_SPtr
+{
+ VALUE *m_p;
+ size_t *m_counter;
+public:
+ AdlMIDI_SPtr() : m_p(NULL), m_counter(NULL) {}
+ ~AdlMIDI_SPtr()
+ {
+ reset(NULL);
+ }
+
+ AdlMIDI_SPtr(const AdlMIDI_SPtr &other)
+ : m_p(other.m_p), m_counter(other.m_counter)
+ {
+ if(m_counter)
+ ++*m_counter;
+ }
+
+ AdlMIDI_SPtr &operator=(const AdlMIDI_SPtr &other)
+ {
+ reset();
+ m_p = other.m_p;
+ m_counter = other.m_counter;
+ if(m_counter)
+ ++*m_counter;
+ return *this;
+ }
+
+ void reset(VALUE *p = NULL)
+ {
+ if(p != m_p) {
+ if(m_p && --*m_counter == 0)
+ delete m_p;
+ m_p = p;
+ if(!p) {
+ if(m_counter) {
+ delete m_counter;
+ m_counter = NULL;
+ }
+ }
+ else
+ {
+ if(!m_counter)
+ m_counter = new size_t;
+ *m_counter = 1;
+ }
+ }
+ }
+
+ VALUE *get()
+ {
+ return m_p;
+ }
+ VALUE &operator*()
+ {
+ return *m_p;
+ }
+ VALUE *operator->()
+ {
+ return m_p;
+ }
};
class MIDIplay;
@@ -173,7 +246,7 @@ public:
char ____padding[4];
ADL_MIDIPlayer *_parent;
#ifndef ADLMIDI_HW_OPL
- std::vector<AdlMIDI_CPtr<OPLChipBase > > cardsOP2;
+ std::vector<AdlMIDI_SPtr<OPLChipBase > > cardsOP2;
#endif
private:
std::vector<size_t> ins; // index to adl[], cached, needed by Touch()