blob: dc6770ba1c1fe96346db944e986d13bf6c8fd4c3 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
// 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
|