00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "pool.h"
00018
00019 #include <stdio.h>
00020
00021
00022
00023 ModulePool *ModulePool::pool=NULL;
00024
00025
00026 _ISharedObject *ModulePool::_FindObjectByName(const char *name,bool requeue)
00027 {
00028 _ISharedObject *res=NULL;
00029
00030 pool_mutex.lock();
00031 for(_ISharedObject *so=so_list.first(); so; so=so->next)
00032 {
00033 if(!strcmp(so->mname,name))
00034 {
00035 res=so;
00036 if(requeue && so->prev)
00037 {
00038
00039 so_list.dequeue(so);
00040 so_list.insert(so);
00041 }
00042 break;
00043 }
00044 }
00045 pool_mutex.unlock();
00046
00047 return(res);
00048 }
00049
00050
00051 SharedObject ModulePool::_load(const char *name,int flags)
00052 {
00053 if(!this || !name) return SharedObject();
00054
00055
00056 _ISharedObject *so=_FindObjectByName(name,1);
00057 if(so)
00058 { return(SharedObject(so)); }
00059
00060
00061
00062
00063 pool_mutex.lock();
00064 GModule *module=g_module_open(name,(GModuleFlags)flags);
00065 if(!module)
00066 {
00067
00068
00069
00070 so=new _ISharedObject(NULL,g_module_error());
00071
00072 }
00073 else
00074 {
00075 so=new _ISharedObject(module,name);
00076
00077 so_list.insert(so);
00078 }
00079 pool_mutex.unlock();
00080
00081 return(SharedObject(so));
00082 }
00083
00084
00085 int ModulePool::_unload(const char *name)
00086 {
00087 if(!this) return(2);
00088 if(!name) return(0);
00089
00090 _ISharedObject *so=_FindObjectByName(name,0);
00091 if(!so) return(1);
00092
00093 _unregister(so);
00094
00095 return(0);
00096 }
00097
00098
00099 void ModulePool::_unregister(_ISharedObject *iso)
00100 {
00101 if(!this || !iso) return;
00102
00103 pool_mutex.lock();
00104 so_list.dequeue(iso);
00105 pool_mutex.unlock();
00106
00107
00108
00109
00110 GModule *module=iso->module;
00111 iso->module=NULL;
00112
00113
00114 if(!g_module_close(module))
00115 {
00116
00117 fprintf(stderr,"OOPS: Failed to unload module %s\n",iso->name());
00118 }
00119 }
00120
00121
00122 int ModulePool::init()
00123 {
00124
00125
00126 if(!g_module_supported())
00127 { return(1); }
00128
00129
00130 new ModulePool();
00131
00132 return(0);
00133 }
00134
00135
00136 void ModulePool::cleanup()
00137 {
00138 if(pool)
00139 { delete pool; }
00140
00141 }
00142
00143
00144 ModulePool::ModulePool() :
00145 so_list(),
00146 pool_mutex()
00147 {
00148 Assert(!pool);
00149 pool=this;
00150 }
00151
00152
00153 ModulePool::~ModulePool()
00154 {
00155 Assert(pool==this);
00156
00157
00158 pool_mutex.lock();
00159 Assert(so_list.IsEmpty());
00160 while(!so_list.IsEmpty())
00161 { _unregister(so_list.first()); }
00162 pool_mutex.unlock();
00163
00164 pool=NULL;
00165 }
00166
00167
00168 #if 0
00169
00170
00171 #include <lib/module/pool.h>
00172 #include <lib/module/symbol.h>
00173
00174 int main()
00175 {
00176 if(ModulePool::init())
00177 { fprintf(stderr,"Modules not supported.\n"); exit(1); }
00178
00179
00180
00181
00182 ModulePool::cleanup();
00183 return(0);
00184 }
00185
00186 void foo()
00187 {
00188 ModuleSymbol sym;
00189
00190 {
00191
00192 SharedObject so=ModulePool::load("mymodule.so");
00193 if(so->error())
00194 { fprintf(stderr,"Failed to load module: %s\n",so->error()); return; }
00195
00196
00197 ModuleSymbol sym_bar=so->lookup("bar");
00198 if(!sym_bar)
00199 { fprintf(stderr,"OOPS: Symbol bar not present in module.\n"); return; }
00200
00201
00202
00203 sym=sym_bar;
00204
00205
00206
00207
00208 }
00209
00210 typedef int (*bar_fptr)(double);
00211
00212
00213 (*(bar_fptr)sym.ptr())( 3.14 );
00214
00215
00216
00217 ModuleFunction<int(*)(double)> bar=sym;
00218 (*bar)( 3.14 );
00219
00220
00221
00222 sym=ModuleSymbol();
00223
00224
00225
00226
00227
00228
00229 }
00230 #endif