diff options
author | Florian Jung <flo@thinkpad.(none)> | 2011-01-11 16:46:38 +0100 |
---|---|---|
committer | Florian Jung <flo@thinkpad.(none)> | 2011-01-11 16:57:57 +0100 |
commit | 8201450efc105691e343c50b4eab946f7b0ee038 (patch) | |
tree | 70c0dd8c26740db888a7e7d096a6be7b1ed85353 /synth | |
parent | db04e2fb861ed7ccef5a7339e9860ca5c2590a7c (diff) |
Now keeping track of unused shared objects and maybe unloading them
Diffstat (limited to 'synth')
-rw-r--r-- | synth/.depend | 21 | ||||
-rw-r--r-- | synth/Makefile | 2 | ||||
-rw-r--r-- | synth/note_loader.cpp | 10 | ||||
-rw-r--r-- | synth/programs.cpp | 10 | ||||
-rw-r--r-- | synth/shared_object_manager.cpp | 65 | ||||
-rw-r--r-- | synth/shared_object_manager.h | 8 |
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 |