00001 #include "DynLoad.h"
00002 #include <dlfcn.h>
00003 #include <vector>
00004 #include <stdlib.h>
00005 #include <sys/types.h>
00006 #include <sys/stat.h>
00007
00008 using namespace std;
00009
00010
00011 vector < string > gAllObjects;
00012 vector < string > gAllCurFNames;
00013 vector < void * > gAllDLHandles;
00014
00015 vector < int > gRepCounts;
00016 vector < unsigned > gSecTimes;
00017
00018
00019 extern "C"
00020 {
00021 typedef int (*LoaderFunction)();
00022 };
00023
00024 void * OperatingOldVtable;
00025
00026
00027 unsigned DYFileTime( const string sFileName )
00028 {
00029 struct stat sb;
00030 sb.st_mtime = -1;
00031 stat( sFileName.c_str(), &sb );
00032 return sb.st_mtime;
00033 }
00034
00035
00036 bool LoadModule( const string FullModuleName, int iPlace )
00037 {
00038 char buf[1024];
00039 char fname[1024];
00040 sprintf( fname, "%s.%d.sox", FullModuleName.c_str(), gRepCounts[iPlace] );
00041
00042
00043 gSecTimes[iPlace] = DYFileTime( FullModuleName + ".cpp" );
00044
00045
00046 if( gRepCounts[iPlace] != 0 || ( gRepCounts[iPlace] == 0 && ( DYFileTime( fname ) < gSecTimes[iPlace] || DYFileTime( fname ) == -1 ) ) )
00047 {
00048
00049 snprintf( buf, 1023, "./soxizer %s %d", gAllObjects[iPlace].c_str(), gRepCounts[iPlace] );
00050 printf( "Exec: %s\n", buf );
00051 if( system( buf ) != 0 )
00052 {
00053 printf( "Compiling failed. Not loading new version.\n" );
00054 return false;
00055 }
00056 }
00057
00058
00059 {
00060 Node TMPX = NODEMAN->Spawn( gAllObjects[iPlace], "TempObject" );
00061 if( TMPX.Get() )
00062 memcpy( &OperatingOldVtable, TMPX.Get(), sizeof( void* ) );
00063 }
00064
00065 if( gAllDLHandles[iPlace] )
00066 {
00067 dlclose( gAllDLHandles[iPlace] );
00068 if( gAllCurFNames[iPlace].length() > 0 )
00069 {
00070 snprintf( buf, 1023, "rm %s", gAllCurFNames[iPlace].c_str() );
00071 printf( "Exec: %s\n", buf );
00072 system( buf );
00073 }
00074 }
00075
00076 gAllCurFNames[iPlace] = fname;
00077 gAllCurFNames[iPlace] = "./" + gAllCurFNames[iPlace];
00078
00079 gRepCounts[iPlace]++;
00080
00081 gAllDLHandles[iPlace] = dlopen( gAllCurFNames[iPlace].c_str(), RTLD_NOW | RTLD_GLOBAL );
00082 if( !gAllDLHandles[iPlace] )
00083 {
00084 printf( "Error opening: %s\n", gAllCurFNames[iPlace].c_str() );
00085 return false;
00086 }
00087 LoaderFunction T = (LoaderFunction)dlsym( gAllDLHandles[iPlace], "RegisterAllInShared" );
00088 if( !gAllDLHandles[iPlace] )
00089 {
00090 printf( "Error finding: RegisterallInShareD() in %s\n", gAllCurFNames[iPlace].c_str() );
00091 return false;
00092 }
00093 T();
00094
00095 return true;
00096 }
00097
00098
00099 bool UpdateDynLoad()
00100 {
00101 static unsigned cur = 0;
00102 cur = (cur+1)%gAllObjects.size();
00103
00104 if( gSecTimes[cur] != DYFileTime( gAllObjects[cur] + ".cpp" ) )
00105 {
00106 LoadModule( gAllObjects[cur], cur );
00107 }
00108 }
00109
00110 bool InitDynLoad()
00111 {
00112 FILE * f = fopen( "modules.lst", "r" );
00113 if( !f )
00114 {
00115 printf( "Error. could not open modules.lst.\n" );
00116 return false;
00117 }
00118
00119 while( !feof( f ) && !ferror( f ) )
00120 {
00121 char buffer[128];
00122 fscanf( f, "%127s\n", buffer );
00123 gAllObjects.push_back( buffer );
00124 gAllDLHandles.push_back( 0 );
00125 gAllCurFNames.push_back( "" );
00126 gRepCounts.push_back( 0 );
00127 gSecTimes.push_back( 0 );
00128
00129 if( !LoadModule( (gAllObjects[gAllObjects.size()-1] ), gAllObjects.size()-1 ) )
00130 return false;
00131 }
00132
00133 fclose( f );
00134 return true;
00135 }
00136
00137 void RuntimeRegisterObject( const char * sName, ProducerFunct t )
00138 {
00139
00140 NodeManager::Instance()->RegisterType( sName, t);
00141
00142 map< string, NodeObject* > * inst = NodeManager::Instance()->GetObjectInstanceMap();
00143
00144
00145 NodeObject * TempObject = t( "TempObject" );
00146 void * newVTable;
00147 memcpy( &newVTable, TempObject, sizeof( void* ) );
00148 delete TempObject;
00149
00150
00151
00152 for( map< string, NodeObject * >::iterator i = inst->begin();
00153 i != inst->end(); i++ )
00154 {
00155 if( memcmp( (i->second), &OperatingOldVtable, sizeof( void * ) ) == 0 )
00156 memcpy( (i->second), &newVTable, sizeof( void*) );
00157 }
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182