summaryrefslogtreecommitdiff
path: root/synth
diff options
context:
space:
mode:
authorFlorian Jung <flo@thinkpad.(none)>2011-01-11 16:46:38 +0100
committerFlorian Jung <flo@thinkpad.(none)>2011-01-11 16:57:57 +0100
commit8201450efc105691e343c50b4eab946f7b0ee038 (patch)
tree70c0dd8c26740db888a7e7d096a6be7b1ed85353 /synth
parentdb04e2fb861ed7ccef5a7339e9860ca5c2590a7c (diff)
Now keeping track of unused shared objects and maybe unloading them
Diffstat (limited to 'synth')
-rw-r--r--synth/.depend21
-rw-r--r--synth/Makefile2
-rw-r--r--synth/note_loader.cpp10
-rw-r--r--synth/programs.cpp10
-rw-r--r--synth/shared_object_manager.cpp65
-rw-r--r--synth/shared_object_manager.h8
6 files changed, 102 insertions, 14 deletions
diff --git a/synth/.depend b/synth/.depend
index fb0d8aa..ba430bb 100644
--- a/synth/.depend
+++ b/synth/.depend
@@ -9,12 +9,12 @@ filter.o: filter.cpp filter.h fixed.h defines.h globals.h programs.h \
globals.o: globals.cpp globals.h programs.h fixed.h note_funcs.h \
channel.h note_skel.h defines.h util.h
jack.o: jack.cpp defines.h globals.h programs.h fixed.h note_funcs.h \
- channel.h note_skel.h util.h jack.h
+ channel.h note_skel.h util.h jack.h communication.h
load.o: load.cpp util.h programs.h fixed.h note_funcs.h globals.h \
- channel.h note_skel.h defines.h
-main.o: main.cpp jack.h load.h cli.h parser.h fixed.h programs.h \
- note_funcs.h channel.h note_skel.h defines.h util.h globals.h \
- note_loader.h
+ channel.h note_skel.h defines.h parser.h note_loader.h
+main.o: main.cpp jack.h load.h programs.h fixed.h note_funcs.h cli.h \
+ channel.h note_skel.h defines.h util.h globals.h in_synth_cli.h \
+ communication.h note_loader.h
note.o: note.cpp note.h programs.h fixed.h note_funcs.h envelope.h \
filter.h note_skel.h globals.h channel.h defines.h util.h
note_skel.o: note_skel.cpp note_skel.h programs.h fixed.h note_funcs.h \
@@ -22,10 +22,17 @@ note_skel.o: note_skel.cpp note_skel.h programs.h fixed.h note_funcs.h \
parser.o: parser.cpp parser.h fixed.h programs.h note_funcs.h defines.h \
globals.h channel.h note_skel.h util.h readwave.h
programs.o: programs.cpp programs.h fixed.h note_funcs.h globals.h \
- channel.h note_skel.h defines.h util.h
+ channel.h note_skel.h defines.h util.h shared_object_manager.h
readwave.o: readwave.cpp readwave.h programs.h fixed.h note_funcs.h \
util.h
util.o: util.cpp util.h programs.h fixed.h note_funcs.h globals.h \
channel.h note_skel.h defines.h
note_loader.o: note_loader.cpp note_loader.h programs.h fixed.h \
- note_funcs.h globals.h channel.h note_skel.h defines.h util.h
+ note_funcs.h globals.h channel.h note_skel.h defines.h util.h \
+ shared_object_manager.h
+in_synth_cli.o: in_synth_cli.cpp in_synth_cli.h util.h programs.h fixed.h \
+ note_funcs.h communication.h globals.h channel.h note_skel.h defines.h \
+ load.h
+communication.o: communication.cpp communication.h
+shared_object_manager.o: shared_object_manager.cpp util.h programs.h \
+ fixed.h note_funcs.h shared_object_manager.h
diff --git a/synth/Makefile b/synth/Makefile
index 2f16297..8109bc8 100644
--- a/synth/Makefile
+++ b/synth/Makefile
@@ -3,7 +3,7 @@ CFLAGS=-Wall -g
CXXFLAGS=$(CFLAGS)
LDFLAGS=-lm `pkg-config --cflags --libs jack`
-OBJ=channel.o cli.o defines.o envelope.o filter.o globals.o jack.o load.o main.o note.o note_skel.o parser.o programs.o readwave.o util.o note_loader.o in_synth_cli.o communication.o
+OBJ=channel.o cli.o defines.o envelope.o filter.o globals.o jack.o load.o main.o note.o note_skel.o parser.o programs.o readwave.o util.o note_loader.o in_synth_cli.o communication.o shared_object_manager.o
BIN=synth
DEPENDFILE = .depend
diff --git a/synth/note_loader.cpp b/synth/note_loader.cpp
index 28613b9..d322552 100644
--- a/synth/note_loader.cpp
+++ b/synth/note_loader.cpp
@@ -6,6 +6,7 @@
#include "programs.h"
#include "note_funcs.h"
#include "globals.h"
+#include "shared_object_manager.h"
using namespace std;
@@ -13,10 +14,7 @@ void load_note_from_so(string file, program_t &prog)
{
void *handle;
- handle = dlopen(file.c_str(), RTLD_LAZY);
-
- if (handle==NULL)
- throw string("could not open shared object (")+string(dlerror())+string(")");
+ handle = my_dlopen(file);
try
{
@@ -38,7 +36,7 @@ void load_note_from_so(string file, program_t &prog)
{
prog.create_func=NULL;
prog.dl_handle=NULL;
- dlclose(handle);
+ dlref_dec(handle);
throw err;
}
}
@@ -47,7 +45,7 @@ void maybe_unload_note(program_t &prog)
{
if (prog.dl_handle)
{
- dlclose(prog.dl_handle);
+ dlref_dec(prog.dl_handle);
prog.dl_handle=NULL;
prog.create_func=NULL;
}
diff --git a/synth/programs.cpp b/synth/programs.cpp
index 094f209..b896a06 100644
--- a/synth/programs.cpp
+++ b/synth/programs.cpp
@@ -1,8 +1,10 @@
#include <string>
#include <cstring>
+#include <dlfcn.h>
#include "programs.h"
#include "globals.h"
+#include "shared_object_manager.h"
using namespace std;
@@ -78,6 +80,12 @@ void program_t::cleanup()
delete [] pfactor.fm[i];
delete [] pfactor.fm;
}
+
+ if (dl_handle)
+ dlref_dec(dl_handle);
+
+ dl_handle=NULL;
+ create_func=NULL;
}
program_t& program_t::operator=(const program_t &that)
@@ -121,6 +129,8 @@ program_t& program_t::operator=(const program_t &that)
this->create_func=that.create_func;
this->dl_handle=that.dl_handle;
+ if (dl_handle)
+ dlref_inc(dl_handle);
return *this;
}
diff --git a/synth/shared_object_manager.cpp b/synth/shared_object_manager.cpp
new file mode 100644
index 0000000..045f409
--- /dev/null
+++ b/synth/shared_object_manager.cpp
@@ -0,0 +1,65 @@
+#include <dlfcn.h>
+#include <map>
+#include <string>
+
+#include "util.h"
+#include "shared_object_manager.h"
+
+using namespace std;
+
+map<void*, int> dl_ref_count;
+
+void* my_dlopen(string file)
+{
+ void* handle;
+
+ if (file.find('/')==string::npos)
+ file="./"+file;
+
+ handle=dlopen(file.c_str(),RTLD_NOW);
+
+ if (handle==NULL)
+ throw string("could not open shared object (")+string(dlerror())+string(")");
+
+ if (dl_ref_count[handle]!=0) //the library is already opened
+ {
+ output_verbose("the requested shared object '"+file+"' is already opened, reusing the handle #"+IntToStr(int(handle)));
+ dlclose(handle); //we don't need it opened twice
+ }
+ else
+ {
+ output_verbose("the requested shared object '"+file+"' has been loaded with handle #"+IntToStr(int(handle)));
+ }
+
+ dl_ref_count[handle]++;
+
+ return handle;
+}
+
+void dlref_inc(void* handle)
+{
+ if (handle==NULL)
+ throw string("dlref_inc: tried to increment the ref-count for NULL");
+
+ if (dl_ref_count[handle]==0)
+ throw string("dlref_inc: tried to increment the ref-count for a nonexistent handle");
+
+ dl_ref_count[handle]++;
+}
+
+void dlref_dec(void* handle)
+{
+ if (handle==NULL)
+ throw string("dlref_inc: tried to increment the ref-count for NULL");
+
+ if (dl_ref_count[handle]==0)
+ throw string("dlref_inc: tried to decrement the ref-count for a nonexistent handle");
+
+ dl_ref_count[handle]--;
+
+ if (dl_ref_count[handle]==0)
+ {
+ output_verbose("noone uses dl-handle "+IntToStr(int(handle))+", unloading the shared object...");
+ dlclose(handle);
+ }
+}
diff --git a/synth/shared_object_manager.h b/synth/shared_object_manager.h
new file mode 100644
index 0000000..5927408
--- /dev/null
+++ b/synth/shared_object_manager.h
@@ -0,0 +1,8 @@
+#ifndef __SHARED_OBJECT_MANAGER__
+#define __SHARED_OBJECT_MANAGER__
+
+void* my_dlopen(string file);
+void dlref_inc(void* handle);
+void dlref_dec(void* handle);
+
+#endif