was never stable until usleep(100000);void WINAPI CALLBACK PerlCallback(HINTERNET h, DWORD context, DWORD mystatus, LPVOID mystatusinfo, DWORD mystatuslength) { DWORD myret; HINTERNET myhandle; // Let's try with perl_call_method // ...to clarify: // a C routine // called from Perl // callbacks this C routine // that callbacks a Perl routine. // ;) // if(mystatus!=status) { SV **sp; HANDLE hMutex; char mutexname [sizeof("Win32InternetPerlMutex") + sizeof(DW +ORD)*8]; DWORD waitres; //char [23 + sizeof(DWORD)*8] mutexname; //void * myptr; //printf("PerlCallback: entering\n"); printf("PerlCallback: got handle=%d context=%d mystatus=%d\n", +h,context,mystatus); //printf("PerlCallback: myWin32InternetPerlInterpreterPtr=%p\n +",myWin32InternetPerlInterpreterPtr); //comment below out to trigger original crash/bug in Win32::In +ternet and recompile PERL_SET_CONTEXT(myWin32InternetPerlInterpreterPtr); //printf("PerlCallback: ThreadId=%d\n",GetCurrentThreadId()); //printf("PerlCallback: GetLastError() =%d\n",GetLastError()); //myptr = PERL_GET_CONTEXT; //printf("PerlCallback: GetLastError() =%d\n",GetLastError()); //printf("PerlCallback: pointer from Perl_get_context() =%p\n" +,myptr); //can't use dSP because we are after variable declarations sp = PL_stack_sp; ENTER; SAVETMPS; PUSHMARK(sp); // XPUSHs(sv_2mortal(newSVpv("Win32::Internet\0",0))); XPUSHs(sv_2mortal(newSViv(context))); XPUSHs(sv_2mortal(newSViv(mystatus))); switch(mystatus) { case INTERNET_STATUS_HANDLE_CREATED: myhandle=(HINTERNET) *(LPHINTERNET)mystatusinfo; XPUSHs(sv_2mortal(newSViv((DWORD) myhandle))); break; case INTERNET_STATUS_RESPONSE_RECEIVED: case INTERNET_STATUS_REQUEST_SENT: myret=(DWORD) *(LPDWORD)mystatusinfo; // printf("PerlCallback: received/sent(%d) %d bytes\n",mys +tatus,myret); XPUSHs(sv_2mortal(newSViv(myret))); break; default: XPUSHs(sv_2mortal(newSViv(0))); break; } PUTBACK; // printf("PerlCallback: calling callback with context=%d, sta +tus=%d\n",context,mystatus); sprintf(mutexname ,"Win32InternetPerlMutex%u", GetCurrentPro +cessId()); //printf("PerlCallback: mutexname=%s\n",mutexname); hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, mutexname); if (hMutex == NULL) printf("PerlCallback: OpenMutex error: % +d\n", GetLastError() ); else printf("PerlCallback: OpenMutex successfully opened the + mutex.\n"); waitres = WaitForSingleObject(hMutex,500000); printf("PerlCallback: wait result =%d\n",waitres); perl_call_pv("Win32::Internet::callback", G_DISCARD); printf("PerlCallback: release mutex res=%d\n",ReleaseMutex(h +Mutex)); CloseHandle(hMutex); FREETMPS; LEAVE; // } // status=mystatus; // return; }
Only 1 out of 5 runs weren't stable at usleep(10000); in the getstatus loop in the test script.void WINAPI CALLBACK PerlCallback(HINTERNET h, DWORD context, DWORD mystatus, LPVOID mystatusinfo, DWORD mystatuslength) { DWORD myret; HINTERNET myhandle; // Let's try with perl_call_method // ...to clarify: // a C routine // called from Perl // callbacks this C routine // that callbacks a Perl routine. // ;) // if(mystatus!=status) { SV **sp; HANDLE hMutex; char mutexname [sizeof("Win32InternetPerlMutex") + sizeof(DW +ORD)*8]; DWORD waitres; //char [23 + sizeof(DWORD)*8] mutexname; //void * myptr; //printf("PerlCallback: entering\n"); sprintf(mutexname ,"Win32InternetPerlMutex%u", GetCurrentPro +cessId()); //printf("PerlCallback: mutexname=%s\n",mutexname); hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, mutexname); if (hMutex == NULL) printf("PerlCallback: OpenMutex error: % +d\n", GetLastError() ); else printf("PerlCallback: OpenMutex successfully opened the + mutex.\n"); waitres = WaitForSingleObject(hMutex,500000); printf("PerlCallback: wait result =%d\n",waitres); printf("PerlCallback: got handle=%d context=%d mystatus=%d\n", +h,context,mystatus); //printf("PerlCallback: myWin32InternetPerlInterpreterPtr=%p\n +",myWin32InternetPerlInterpreterPtr); //comment below out to trigger original crash/bug in Win32::In +ternet and recompile PERL_SET_CONTEXT(myWin32InternetPerlInterpreterPtr); //printf("PerlCallback: ThreadId=%d\n",GetCurrentThreadId()); //printf("PerlCallback: GetLastError() =%d\n",GetLastError()); //myptr = PERL_GET_CONTEXT; //printf("PerlCallback: GetLastError() =%d\n",GetLastError()); //printf("PerlCallback: pointer from Perl_get_context() =%p\n" +,myptr); //can't use dSP because we are after variable declarations sp = PL_stack_sp; ENTER; SAVETMPS; PUSHMARK(sp); // XPUSHs(sv_2mortal(newSVpv("Win32::Internet\0",0))); XPUSHs(sv_2mortal(newSViv(context))); XPUSHs(sv_2mortal(newSViv(mystatus))); switch(mystatus) { case INTERNET_STATUS_HANDLE_CREATED: myhandle=(HINTERNET) *(LPHINTERNET)mystatusinfo; XPUSHs(sv_2mortal(newSViv((DWORD) myhandle))); break; case INTERNET_STATUS_RESPONSE_RECEIVED: case INTERNET_STATUS_REQUEST_SENT: myret=(DWORD) *(LPDWORD)mystatusinfo; // printf("PerlCallback: received/sent(%d) %d bytes\n",mys +tatus,myret); XPUSHs(sv_2mortal(newSViv(myret))); break; default: XPUSHs(sv_2mortal(newSViv(0))); break; } PUTBACK; // printf("PerlCallback: calling callback with context=%d, sta +tus=%d\n",context,mystatus); perl_call_pv("Win32::Internet::callback", G_DISCARD); FREETMPS; LEAVE; printf("PerlCallback: release mutex res=%d\n",ReleaseMutex(h +Mutex)); CloseHandle(hMutex); // } // status=mystatus; // return; }
In reply to Re^2: Win32::Internet crash, XS, callbacks, perl stack & context, windows api, interpreter thread safety, 1 perl, many C threads by windows
by patcat88
in thread Win32::Internet crash, XS, callbacks, perl stack & context, windows api, interpreter thread safety, 1 perl, many C threads by windows
by patcat88
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |