Skip to content

Commit

Permalink
preload
Browse files Browse the repository at this point in the history
  • Loading branch information
i-saint committed Jun 26, 2013
1 parent a15b665 commit 450c5ae
Show file tree
Hide file tree
Showing 9 changed files with 150 additions and 4 deletions.
21 changes: 20 additions & 1 deletion DynamicPatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,16 @@ dpAPI bool dpInitialize(const dpConfig &conf)
}
dpEach(cf.loads, [](const std::string &v){ dpLoad(v.c_str()); });
dpEach(cf.source_paths, [](const std::string &v){ dpAddSourcePath(v.c_str()); });
dpEach(cf.module_paths, [](const std::string &v){ dpAddModulePath(v.c_str()); });
dpEach(cf.module_paths, [](const std::string &v){ dpAddModulePath(v.c_str()); });
dpEach(cf.preload_paths, [](const std::string &v){ dpAddPreloadPath(v.c_str()); });
dpEach(cf.msbuild_commands, [](const std::string &v){ dpAddMSBuildCommand(v.c_str()); });
dpEach(cf.build_commands, [](const std::string &v){ dpAddBuildCommand(v.c_str()); });
if(!cf.source_paths.empty() && (!cf.msbuild_commands.empty() || !cf.build_commands.empty())) {
dpStartAutoBuild();
}
if(!cf.preload_paths.empty()) {
dpStartPreload();
}
}
if((g_dpConfig.sys_flags & dpE_SysOpenConsole)!=0) {
::AllocConsole();
Expand Down Expand Up @@ -152,6 +156,11 @@ dpAPI void dpAddSourcePath(const char *path)
dpGetCurrentContext()->getBuilder()->addSourcePath(path);
}

dpAPI void dpAddPreloadPath(const char *path)
{
dpGetCurrentContext()->getBuilder()->addPreloadPath(path);
}

dpAPI void dpAddMSBuildCommand(const char *msbuild_option)
{
dpGetCurrentContext()->getBuilder()->addMSBuildCommand(msbuild_option);
Expand All @@ -175,6 +184,16 @@ dpAPI bool dpStopAutoBuild()
return dpGetCurrentContext()->getBuilder()->stopAutoBuild();
}

dpAPI bool dpStartPreload()
{
return dpGetCurrentContext()->getBuilder()->startPreload();
}

dpAPI bool dpStopPreload()
{
return dpGetCurrentContext()->getBuilder()->stopPreload();
}

dpAPI void dpUpdate()
{
dpGetCurrentContext()->getBuilder()->update();
Expand Down
6 changes: 6 additions & 0 deletions DynamicPatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,14 @@ dpAPI void* dpGetUnpatched(void *target_or_hook_addr);

dpAPI void dpAddModulePath(const char *path); // accepts wildcard. affects auto build and dpReload()
dpAPI void dpAddSourcePath(const char *path); //
dpAPI void dpAddPreloadPath(const char *path); //
dpAPI void dpAddMSBuildCommand(const char *msbuild_option); // add msbuild command that will be called by auto build thread
dpAPI void dpAddCLBuildCommand(const char *cl_option); // add cl command that will be called by auto build thread
dpAPI void dpAddBuildCommand(const char *any_command); // add arbitrary command that will be called by auto build thread
dpAPI bool dpStartAutoBuild();
dpAPI bool dpStopAutoBuild();
dpAPI bool dpStartPreload();
dpAPI bool dpStopPreload();
dpAPI void dpUpdate(); // reloads and links modified modules.

dpAPI void dpPrint(const char* fmt, ...);
Expand Down Expand Up @@ -183,11 +186,14 @@ dpAPI const char* dpGetVCVarsPath();

#define dpAddModulePath(...)
#define dpAddSourcePath(...)
#define dpAddPreloadPath(...)
#define dpAddMSBuildCommand(...)
#define dpAddCLBuildCommand(...)
#define dpAddBuildCommand(...)
#define dpStartAutoBuild(...)
#define dpStopAutoBuild(...)
#define dpStartPreload(...)
#define dpStopPreload(...)
#define dpUpdate(...)

#define dpPrint(...)
Expand Down
4 changes: 4 additions & 0 deletions DynamicPatcher.sln
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test_Particles", "Test\Test
{7CCD61E5-5F56-4050-BACC-1467972D2247} = {7CCD61E5-5F56-4050-BACC-1467972D2247}
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{C8F1FBCF-D704-474A-990B-A42D1F208C41}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Expand Down Expand Up @@ -185,5 +187,7 @@ Global
{315A0660-7223-41CF-839C-69CF731F8F43} = {64A0BD32-2657-48A5-A8A8-B047C39B0455}
{2B417248-C199-456C-99A3-CD7930E0D6A1} = {64A0BD32-2657-48A5-A8A8-B047C39B0455}
{D29C6982-A589-4081-89B1-91E78D7C41E2} = {64A0BD32-2657-48A5-A8A8-B047C39B0455}
{7986011C-5076-4506-AB77-7272257885FD} = {C8F1FBCF-D704-474A-990B-A42D1F208C41}
{AF9F0E41-895E-49BA-B522-45691F0BD4F7} = {C8F1FBCF-D704-474A-990B-A42D1F208C41}
EndGlobalSection
EndGlobal
3 changes: 0 additions & 3 deletions dpBinary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,6 @@ bool dpObjFile::loadMemory(const char *path, void *data, size_t size, dpTime mti
}
if(dpSymbol *s=getSymbolTable().findSymbolByName(g_symname_onload)) { s->flags |= dpE_Handler; }
if(dpSymbol *s=getSymbolTable().findSymbolByName(g_symname_onunload)) { s->flags |= dpE_Handler; }

dpGetLoader()->addOnLoadList(this);
return true;
}

Expand Down Expand Up @@ -664,7 +662,6 @@ bool dpDllFile::loadMemory(const char *path, void *data, size_t /*datasize*/, dp
m_symbols.addSymbol(dpGetLoader()->newSymbol(name, sym, dpE_Code|dpE_Read|dpE_Execute|dpE_Export, 0, this));
});
m_symbols.sort();
dpGetLoader()->addOnLoadList(this);
return true;
}

Expand Down
69 changes: 69 additions & 0 deletions dpBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ dpBuilder::dpBuilder(dpContext *ctx)
, m_build_done(false)
, m_watchfile_stop(false)
, m_thread_autobuild(nullptr)
, m_thread_preload(nullptr)
, m_preload_stop(false)
{
std::string VCVersion;
switch(dpGetConfig().vc_ver) {
Expand Down Expand Up @@ -46,6 +48,7 @@ dpBuilder::dpBuilder(dpContext *ctx)
dpBuilder::~dpBuilder()
{
stopAutoBuild();
stopPreload();
}

void dpBuilder::addModulePath(const char *path)
Expand All @@ -70,6 +73,16 @@ void dpBuilder::addSourcePath(const char *path)
if(p==m_srcpathes.end()) { m_srcpathes.push_back(tmp); }
}

void dpBuilder::addPreloadPath( const char *path )
{
std::string tmp = path;
auto p = dpFind(m_preloadpathes, [&](const std::string &s){return s==tmp;});
if(p==m_preloadpathes.end()) {
std::string s=tmp; dpSanitizePath(s);
m_preloadpathes.push_back(s);
}
}

void dpBuilder::addMSBuildCommand(const char *msbuild_options)
{
std::string cmd = m_vcvars;
Expand Down Expand Up @@ -222,6 +235,62 @@ size_t dpBuilder::reload()
return n;
}


static void Preload( LPVOID arg )
{
((dpBuilder*)arg)->preload();
}

void dpBuilder::preload()
{
for(size_t pi=0; pi<m_preloadpathes.size(); ++pi) {
dpGlob(m_preloadpathes[pi].c_str(), [&](const std::string &path){
if(m_preload_stop) { return; }

dpObjFile *obj = new dpObjFile(m_context);
if(obj->loadFile(path.c_str())) {
dpPrintInfo("preload begin %s\n", path.c_str());
obj->eachSymbols([&](dpSymbol *sym){
if(m_preload_stop) { return; }
if(dpIsExportFunction(sym->flags)) {
dpMutex::ScopedLock lock(m_mtx_preload);
sym->partialLink();
dpGetLoader()->findHostSymbolByName(sym->name);
}
});
dpPrintInfo("preload end %s\n", path.c_str());
}
delete obj;
});
}
}

bool dpBuilder::startPreload()
{
if(!m_thread_preload) {
m_thread_preload = (HANDLE)_beginthread( Preload, 0, this );
dpPrintInfo("preload thread started\n");
return true;
}
return false;
}

bool dpBuilder::stopPreload()
{
if(m_thread_preload) {
m_preload_stop = true;
::WaitForSingleObject(m_thread_preload, INFINITE);
m_thread_preload = nullptr;
dpPrintInfo("preload thread stopped\n");
return true;
}
return false;
}

void dpBuilder::lockPreload() { m_mtx_preload.lock(); }
void dpBuilder::unlockPreload() { m_mtx_preload.unlock(); }


const char* dpBuilder::getVCVarsPath() const
{
return m_vcvars.c_str();
Expand Down
1 change: 1 addition & 0 deletions dpConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ bool dpConfigFile::load(const char *path)
else if(sscanf(line, "load: \"%[^\"]\"", opt)) { loads.push_back(opt); }
else if(sscanf(line, "source path: \"%[^\"]\"", opt)) { source_paths.push_back(opt); }
else if(sscanf(line, "module path: \"%[^\"]\"", opt)) { module_paths.push_back(opt); }
else if(sscanf(line, "preload path: \"%[^\"]\"", opt)) { preload_paths.push_back(opt); }
else if(sscanf(line, "msbuild command: \"%[^\"]\"", opt)) { msbuild_commands.push_back(opt); }
else if(sscanf(line, "build command: \"%[^\"]\"", opt)) { build_commands.push_back(opt); }
}
Expand Down
8 changes: 8 additions & 0 deletions dpFoundation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
#include "dpInternal.h"
#pragma comment(lib, "dbghelp.lib")

dpMutex::ScopedLock::ScopedLock(dpMutex &v) : mutex(v) { mutex.lock(); }
dpMutex::ScopedLock::~ScopedLock() { mutex.unlock(); }
dpMutex::dpMutex() { ::InitializeCriticalSection(&m_cs); }
dpMutex::~dpMutex() { ::DeleteCriticalSection(&m_cs); }
void dpMutex::lock() { ::EnterCriticalSection(&m_cs); }
void dpMutex::unlock() { ::LeaveCriticalSection(&m_cs); }


template<size_t N>
inline int dpVSprintf(char (&buf)[N], const char *format, va_list vl)
{
Expand Down
37 changes: 37 additions & 0 deletions dpInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,24 @@ inline bool operator==(const dpPatchData &a, const dpPatchData &b) { return a.ta
template<class Container, class F> inline void dpEach(Container &cont, const F &f);
template<class Container, class F> inline auto dpFind(Container &cont, const F &f) -> decltype(cont.begin());

class dpMutex
{
public:
class ScopedLock
{
public:
ScopedLock(dpMutex &v);
~ScopedLock();
dpMutex &mutex;
};
dpMutex();
~dpMutex();
void lock();
void unlock();
private:
CRITICAL_SECTION m_cs;
};

dpConfig& dpGetConfig();
void dpPrintError(const char* fmt, ...);
void dpPrintWarning(const char* fmt, ...);
Expand Down Expand Up @@ -212,6 +230,7 @@ struct dpConfigFile
std::vector<std::string> loads;
std::vector<std::string> source_paths;
std::vector<std::string> module_paths;
std::vector<std::string> preload_paths;
std::vector<std::string> msbuild_commands;
std::vector<std::string> build_commands;
std::string config_path;
Expand Down Expand Up @@ -438,20 +457,34 @@ class dpPatcher
class dpBuilder
{
public:
class ScopedPreloadLock
{
public:
ScopedPreloadLock(dpBuilder *v) : m_builder(v) { m_builder->lockPreload(); }
~ScopedPreloadLock() { m_builder->unlockPreload(); }
dpBuilder *m_builder;
};

dpBuilder(dpContext *ctx);
~dpBuilder();
void addModulePath(const char *path);
void addSourcePath(const char *path);
void addPreloadPath(const char *path);
void addMSBuildCommand(const char *msbuild_options);
void addCLBuildCommand(const char *cl_options);
void addBuildCommand(const char *any_command);
bool startAutoBuild();
bool stopAutoBuild();
bool startPreload();
bool stopPreload();
void lockPreload();
void unlockPreload();

void update();
size_t reload();
void watchFiles();
bool build();
void preload();

const char* getVCVarsPath() const;

Expand All @@ -467,9 +500,13 @@ class dpBuilder
std::vector<std::string> m_build_commands;
std::vector<SourcePath> m_srcpathes;
std::vector<std::string> m_loadpathes;
std::vector<std::string> m_preloadpathes;
mutable bool m_build_done;
bool m_watchfile_stop;
HANDLE m_thread_autobuild;
HANDLE m_thread_preload;
bool m_preload_stop;
dpMutex m_mtx_preload;
};


Expand Down
5 changes: 5 additions & 0 deletions dpLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ void dpLoader::addOnLoadList(dpBinary *bin)
template<class BinaryType>
BinaryType* dpLoader::loadBinaryImpl(const char *path)
{
dpBuilder::ScopedPreloadLock pl(dpGetBuilder());

BinaryType *old = static_cast<BinaryType*>(findBinary(path));
if(old) {
dpTime t = dpGetMTime(path);
Expand All @@ -89,6 +91,7 @@ BinaryType* dpLoader::loadBinaryImpl(const char *path)
if(ret->loadFile(path)) {
if(old) { unloadImpl(old); }
m_binaries.push_back(ret);
addOnLoadList(ret);
dpPrintInfo("loaded \"%s\"\n", ret->getPath());
}
else {
Expand Down Expand Up @@ -142,6 +145,8 @@ size_t dpLoader::reload()

bool dpLoader::link()
{
dpBuilder::ScopedPreloadLock pl(dpGetBuilder());

if(m_onload_queue.empty()) {
return true;
}
Expand Down

0 comments on commit 450c5ae

Please sign in to comment.