summaryrefslogtreecommitdiff
path: root/modl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modl.cpp')
-rw-r--r--modl.cpp98
1 files changed, 98 insertions, 0 deletions
diff --git a/modl.cpp b/modl.cpp
new file mode 100644
index 0000000..17c7b49
--- /dev/null
+++ b/modl.cpp
@@ -0,0 +1,98 @@
+// class modl implementation.
+
+#ifndef MODL_CXX
+#define MODL_CXX
+
+#include <limits.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <stdio.h>
+
+#include "s_mutx.h"
+#include "modl.h"
+
+using namespace std;
+
+modl::modl( )
+{
+ map_mods = new hmap<dynmod*,string>(80);
+ pthread_mutex_init( &mut_map_mods, NULL );
+}
+
+modl::~modl()
+{
+ pthread_mutex_lock ( &mut_map_mods );
+
+ // dlclose all the_module's first!
+ map_mods->run_func ( &modl::dlclose_ );
+
+ // then clean the hash map.
+ map_mods->make_empty ( );
+
+ pthread_mutex_unlock ( &mut_map_mods );
+ pthread_mutex_destroy( &mut_map_mods );
+}
+
+void
+modl::dlclose_( dynmod* mod )
+{
+ dlclose( mod->the_module );
+}
+
+dynmod*
+modl::cache_module( string s_name )
+{
+ void *the_module = NULL;
+ function *the_func = NULL;
+
+ the_module = dlopen( s_name.c_str(), RTLD_NOW );
+
+ if ( the_module == NULL )
+ {
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cerr << "dlerror: " << dlerror() << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+ return NULL;
+ }
+
+ the_func = (function*) dlsym( the_module, "extern_function" );
+
+ if ( the_func == NULL )
+ {
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cerr << "dlerror: " << dlerror() << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+ return NULL;
+ }
+
+#ifdef VERBOSE
+ pthread_mutex_lock ( &s_mutx::get().mut_stdout );
+ cout << MODULEC << s_name << endl;
+ pthread_mutex_unlock( &s_mutx::get().mut_stdout );
+#endif
+
+ dynmod *mod = new dynmod; // encapsulates the function and module handler.
+ mod->the_func = the_func ; // the function to execute
+ mod->the_module = the_module; // the module handler to close if function
+ // is not needed anymore.
+ pthread_mutex_lock ( &mut_map_mods );
+ map_mods->add_elem ( mod, s_name );
+ pthread_mutex_unlock( &mut_map_mods );
+
+// DO NOT CLOSE AS LONG THERE EXIST A POINTER TO THE FUNCTION
+// dlclose( module );
+
+ return mod;
+}
+
+dynmod*
+modl::get_module( string s_name )
+{
+ pthread_mutex_lock ( &mut_map_mods );
+ dynmod* mod = map_mods->get_elem( s_name );
+ pthread_mutex_unlock( &mut_map_mods );
+
+ return ! mod ? cache_module( s_name ) : mod;
+}
+
+#endif