From d7605899193f6f9176d7d3abf9a8d7f4484b483f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 7 Jul 2008 13:09:31 +0900 Subject: [PATCH] Solve some issues with multithreaded apps. --- SConstruct | 4 +- base.py | 6 +-- log.hpp | 130 +++++++++++++++++++++++++++++++++++++++++------------ windows.py | 56 +++++++++++++++-------- 4 files changed, 145 insertions(+), 51 deletions(-) diff --git a/SConstruct b/SConstruct index 52c6f32..193e45a 100644 --- a/SConstruct +++ b/SConstruct @@ -40,6 +40,7 @@ env.Append(CPPDEFINES = [ '_CRT_SECURE_NO_DEPRECATE', '_CRT_NON_CONFORMING_SWPRINTFS', 'WIN32_LEAN_AND_MEAN', + '_USRDLL', ]) if env['debug']: @@ -49,7 +50,7 @@ else: env['PDB'] = '${TARGET.base}.pdb' cflags = [ - '/W3', # warning level + '/W4', # warning level ] if env['debug']: cflags += [ @@ -63,6 +64,7 @@ else: '/Oi', # enable intrinsic functions '/Os', # favor code space ] +cflags += ['/MT'] env.Append(CFLAGS = cflags) env.Append(CXXFLAGS = cflags) diff --git a/base.py b/base.py index dc0be29..ea00342 100644 --- a/base.py +++ b/base.py @@ -164,12 +164,10 @@ class Interface(Type): def wrap_impl(self): print '%s::%s(%s * pInstance) {' % (self.wrap_name(), self.wrap_name(), self.name) - print ' m_pLog = new Log("d3d8trace");' print ' m_pInstance = pInstance;' print '}' print print '%s::~%s() {' % (self.wrap_name(), self.wrap_name()) - print " delete m_pLog;" print '}' print for method in self.itermethods(): @@ -179,14 +177,14 @@ class Interface(Type): else: print ' %s result;' % method.type result = 'result = ' - print ' m_pLog->BeginCall("%s");' % (self.name + '::' + method.name) + print ' g_pLog->BeginCall("%s");' % (self.name + '::' + method.name) print ' %sm_pInstance->%s(%s);' % (result, method.name, ', '.join([str(name) for type, name in method.args])) + print ' g_pLog->EndCall();' for type, name in method.args: if type.isoutput(): type.wrap_instance(name) if method.type is not Void: method.type.wrap_instance('result') - print ' m_pLog->EndCall();' if method.name == 'QueryInterface': print ' if(*ppvObj == m_pInstance)' print ' *ppvObj = this;' diff --git a/log.hpp b/log.hpp index 2982a9f..df2cdc4 100644 --- a/log.hpp +++ b/log.hpp @@ -2,29 +2,115 @@ #ifndef _LOG_HPP_ #define _LOG_HPP_ +#include +#include #include -#include -class Log +class File { public: - Log(const char *name) { - char fileName[_MAX_PATH]; - _snprintf(fileName, _MAX_PATH, "%s.%u.xml", name, rand()); - file = fopen(fileName, "wt"); - Write("\n"); - Write("\n"); - Write("\n"); + File(const TCHAR *szName, const TCHAR *szExtension) { + m_hFile = INVALID_HANDLE_VALUE; + Open(szName, szExtension); + } + + ~File() { + Close(); + } + + void Open(const TCHAR *szName, const TCHAR *szExtension) { + Close(); + + DWORD dwCounter = 0; + do { + if(dwCounter) + _sntprintf(szFileName, MAX_PATH, TEXT("%s.%u.%s"), szName, dwCounter, szExtension); + else + _sntprintf(szFileName, MAX_PATH, TEXT("%s.%s"), szName, szExtension); + + m_hFile = CreateFile(szFileName, + GENERIC_WRITE, + FILE_SHARE_WRITE, + NULL, + CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, + NULL); + ++dwCounter; + } while(m_hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_EXISTS); + } + + void ReOpen(void) { + Close(); + + m_hFile = CreateFile(szFileName, + GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + } + + void Close(void) { + if(m_hFile != INVALID_HANDLE_VALUE) { + CloseHandle(m_hFile); + m_hFile = INVALID_HANDLE_VALUE; + } + } + + void Write(const char *szText) { + if(m_hFile == INVALID_HANDLE_VALUE) + return; + + DWORD dwBytesToWrite = (DWORD)strlen(szText); + DWORD dwBytesWritten = 0; + + while (dwBytesWritten < dwBytesToWrite) { + OVERLAPPED overlapped; + memset(&overlapped, 0, sizeof(OVERLAPPED)); + + /* Write to end of file */ + overlapped.Offset = 0xffffffff; + overlapped.OffsetHigh = 0xffffffff; + + if(WriteFile(m_hFile, + szText + dwBytesWritten, + dwBytesToWrite - dwBytesWritten, + &dwBytesWritten, + &overlapped) == FALSE) { + Close(); + Open(TEXT("extra"), TEXT("xml")); + return; + } + } + } + +private: + HANDLE m_hFile; + TCHAR szFileName[MAX_PATH]; +}; + + +class Log : public File +{ +public: + Log(const TCHAR *szName) : File(szName, TEXT("xml")) { + Write(""); + NewLine(); + Write(""); + NewLine(); + Write(""); + NewLine(); } ~Log() { - Write("\n"); - fclose(file); + Write(""); + NewLine(); } void NewLine(void) { - Write("\n"); + Write("\r\n"); } void Tag(const char *name) { @@ -77,10 +163,12 @@ public: } void TextF(const char *format, ...) { + char szBuffer[4196]; va_list ap; va_start(ap, format); - vfprintf(file, format, ap); + vsnprintf(szBuffer, sizeof(szBuffer), format, ap); va_end(ap); + Escape(szBuffer); } void BeginCall(const char *function) { @@ -105,7 +193,7 @@ public: NewLine(); } - void BeginReturn(const char *type, const char *name) { + void BeginReturn(const char *type) { Write("\t\t"); BeginTag("return", "type", type); } @@ -120,20 +208,6 @@ protected: /* FIXME */ Write(s); } - - void Write(const char *s) { - fputs(s, file); - } - - void WriteF(const char *f, ...) { - va_list ap; - va_start(ap, f); - vfprintf(file, f, ap); - va_end(ap); - } - -private: - FILE *file; }; diff --git a/windows.py b/windows.py index 8c7e3a0..8e8adee 100644 --- a/windows.py +++ b/windows.py @@ -71,40 +71,50 @@ class Dll: pass def wrap_decl(self): - print '#pragma data_seg (".%s_shared")' % self.name print 'static HINSTANCE g_hDll = NULL;' print 'static Log * g_pLog = NULL;' - print '#pragma data_seg ()' + print 'static TCHAR g_szDll[MAX_PATH] = {0};' print print 'BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);' print def wrap_impl(self): print r'BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {' - print r' TCHAR fileName[MAX_PATH];' + #print r' Log * pLog;' print r' switch(fdwReason) {' print r' case DLL_PROCESS_ATTACH:' - print r' if(!GetSystemDirectory(fileName, MAX_PATH))' + print r' if(!GetSystemDirectory(g_szDll, MAX_PATH))' print r' return FALSE;' - print r' _tcscat(fileName, TEXT("\\%s.dll"));' % self.name - print r' if(!g_hDll)' - print r' g_hDll = LoadLibrary(fileName);' - print r' if(!g_hDll)' - print r' return FALSE;' - print r' if(!g_pLog)' - print r' g_pLog = new Log("%s");' % self.name + print r' _tcscat(g_szDll, TEXT("\\%s.dll"));' % self.name + #print r' if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)' + #print r' return FALSE;' + #print r' if(!g_pLog)' + #print r' g_pLog = new Log(TEXT("%s"));' % self.name + print r' case DLL_THREAD_ATTACH:' + #print r' pLog = new Log(TEXT("%s"));' % self.name + #print r' TlsSetValue(dwTlsIndex, pLog);' + print r' return TRUE;' + print r' case DLL_THREAD_DETACH:' + #print r' pLog = (Log *)TlsGetValue(dwTlsIndex);' + #print r' if (pLog != NULL)' + #print r' delete pLog;' print r' return TRUE;' print r' case DLL_PROCESS_DETACH:' - print r' if(g_pLog)' + #print r' pLog = (Log *)TlsGetValue(dwTlsIndex);' + #print r' if (pLog != NULL)' + #print r' delete pLog;' + #print r' TlsFree(dwTlsIndex);' + print r' if(g_pLog) {' print r' delete g_pLog;' - print r' if(g_hDll)' + print r' g_pLog = NULL;' + print r' }' + print r' if(g_hDll) {' print r' FreeLibrary(g_hDll);' - print r' return TRUE;' - print r' case DLL_THREAD_ATTACH:' - print r' return TRUE;' - print r' case DLL_THREAD_DETACH:' + print r' g_hDll = NULL;' + print r' }' print r' return TRUE;' print r' }' + print r' (void)hinstDLL;' print r' (void)lpvReserved;' print r' return TRUE;' print r'}' @@ -112,6 +122,11 @@ class Dll: for function in self.functions: type = 'P' + function.name print function.prototype() + ' {' + if 1: + print ' if(g_pLog)' + print ' delete g_pLog;' + print ' g_pLog = new Log(TEXT("%s"));' % self.name + #print ' g_pLog->ReOpen();' print ' typedef ' + function.prototype('* %s' % type) + ';' print ' %s pFunction;' % type if function.type is Void: @@ -119,17 +134,22 @@ class Dll: else: print ' %s result;' % function.type result = 'result = ' + print ' if(!g_hDll) {' + print ' g_hDll = LoadLibrary(g_szDll);' + print ' if(!g_hDll)' + print ' ExitProcess(0);' + print ' }' print ' pFunction = (%s)GetProcAddress( g_hDll, "%s");' % (type, function.name) print ' if(!pFunction)' print ' ExitProcess(0);' print ' g_pLog->BeginCall("%s");' % (function.name) print ' %spFunction(%s);' % (result, ', '.join([str(name) for type, name in function.args])) + print ' g_pLog->EndCall();' for type, name in function.args: if type.isoutput(): type.wrap_instance(name) if function.type is not Void: function.type.wrap_instance('result') - print ' g_pLog->EndCall();' if function.type is not Void: print ' return result;' print '}' -- 2.45.2