monoceres Posted May 10, 2009 Share Posted May 10, 2009 (edited) I'm having troubles with having a custom made dll call callbacks to my au3 script. The thing that makes this error prone is that the dll calls the autoit callback from a new thread. To illustrate the problem I'm having I made the following sources. Dll source: #include <windows.h> typedef void CALLBACK AUTOITCALLBACK(int); DWORD WINAPI DoSomething(void* param) { AUTOITCALLBACK *callback=((AUTOITCALLBACK*)param); Sleep(500); // Do something that takes a while.. callback(1337); return 0; } extern "C" __declspec(dllexport) void asyncjob(AUTOITCALLBACK *callback) { CreateThread(NULL,0,DoSomething,(void*)callback,0,NULL); Sleep(25); // Gives the thread time to copy the callback ptr } Au3 source: Global $runloop=True $cb=DllCallbackRegister("f","none","int") $dll=DllOpen("testbug.dll") DllCall($dll,"none:cdecl","asyncjob","ptr",DllCallbackGetPtr($cb)) While $runloop; Never quits Sleep(10) WEnd Func f($x) MsgBox(0,"",$x); Works ok. box(); Doesn't execute $runloop=false; Fails to change $runloop EndFunc func box() MsgBox(0,"","") EndFu I'm guessing this have to do with autoit not being thread safe, and if that's the case how should I solve my problem? Thanks. Edited May 10, 2009 by monoceres Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
monoceres Posted May 10, 2009 Author Share Posted May 10, 2009 So to summarize the whole thing, why can't I modify variables and call user defined functions when a callback is running in the context of a different thread? Reading variables and calling built in functions works as expected. Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
Authenticity Posted May 11, 2009 Share Posted May 11, 2009 I think you're making a deadlock of some sort ;] can't be sure. This for example return correctly and the script exits eventually. I know it's not sane to compute how much time the called function requires... Global $runloop=True $cb=DllCallbackRegister("f","none","int") $dll=DllOpen("test.dll") DllCall($dll,"none:cdecl","asyncjob","ptr",DllCallbackGetPtr($cb)) While $runloop; Never quits Sleep(10) WEnd Func f($x) MsgBox(0, '', $x) ;ConsoleWrite($x & @LF); Works ok. ;box(); Doesn't execute $runloop=false; Fails to change $runloop EndFunc func box() MsgBox(0, '', '') ;ConsoleWrite('Data' & @LF) EndFuncoÝ÷ Ø«zZr)ànZ)àq©e³*.®Ç+kº{,-¡×¢Énuî´Â)Ý£!ëh§r[{-r«ÊyûèÐ,°@ LâËãH§·CXäCX@ #include <windows.h> #include <tchar.h> typedef void CALLBACK AUTOITCALLBACK(int); DWORD WINAPI DoSomething(void* param) { AUTOITCALLBACK *callback=((AUTOITCALLBACK*)param); HANDLE hSemaphore = CreateSemaphore(NULL, 1, 1, _T("Semama")); Sleep(500); // Do something that takes a while.. callback(1337); WaitForSingleObject(hSemaphore, INFINITE); CloseHandle(hSemaphore); MessageBox(NULL, _T("Text"), _T("Title"), MB_OK | MB_ICONINFORMATION); ExitThread(0); } extern "C" __declspec(dllexport) void asyncjob(AUTOITCALLBACK *callback) { CreateThread(NULL,0,DoSomething,(void*)callback,0,NULL); Sleep(50); // Gives the thread time to copy the callback ptr } Link to comment Share on other sites More sharing options...
Valik Posted May 11, 2009 Share Posted May 11, 2009 (edited) What happens if you don't use MsgBox()? What about using ConsoleWrite()? Please try the original DLL from the first post as well as the original code except replace the MsgBox() calls with ConsoleWrite(). The synchronization code should not be necessary.Edit: It's important that you use ConsoleWrite() and not something else because I know the code execution path for that particular function. Edited May 11, 2009 by Valik Link to comment Share on other sites More sharing options...
monoceres Posted May 11, 2009 Author Share Posted May 11, 2009 Very interesting, it's indeed working fine without the MsgBox() calls. Any ideas why MsgBox makes the callback stop executing and more important, what other functions will produce the same freeze? Is this perhaps linked with the fact that autoit creates an extra thread for the call to MessageBox? Broken link? PM me and I'll send you the file! Link to comment Share on other sites More sharing options...
Valik Posted May 11, 2009 Share Posted May 11, 2009 Simple way to test: Try InetGet(). It creates another thread to do the download. However, I suspect it's something else. I'm trying to remember the circumstances but I've dead-locked stuff before by using a GUI (probably MessageBox()) too early before. I can't remember the exact circumstances, though. Link to comment Share on other sites More sharing options...
Authenticity Posted May 11, 2009 Share Posted May 11, 2009 (edited) Don't know if you mind but even without blocking functions or popping up a GUI you can easily lock the script. Consider this for example, you can change it with a sleep(500) call or other time consuming function execution: #include <Array.au3> Global $runloop=True Global $avArray[3] = ['1', '2', '3'] $cb=DllCallbackRegister("f","none","int") $dll=DllOpen("test.dll") DllCall($dll,"none:cdecl","asyncjob","ptr",DllCallbackGetPtr($cb)) While $runloop; Never quits Sleep(10) WEnd Func f($x) Local $j = 0 For $i = 1 To 0x10000 $j = $i*BitXOR($i, $j); Works ok. Next $runloop=false; Fails to change $runloop EndFunc It still locks the entire script somewhere in the For..Next loop. So you can't say that ConsoleWrite will solve the case. It's an asynchronous case here. Correct me where I'm wrong. Edited May 11, 2009 by Authenticity Link to comment Share on other sites More sharing options...
Valik Posted May 11, 2009 Share Posted May 11, 2009 So you can't say that ConsoleWrite will solve the case.I don't recall saying that it would solve the problem. It was a test to try to isolate the problem, nothing more. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now