Merge branch 'master' of ssh://boinc.berkeley.edu/boinc-v2

This commit is contained in:
David Anderson 2013-03-23 13:22:59 -07:00
commit 210b0ca39f
1 changed files with 69 additions and 53 deletions

View File

@ -100,10 +100,15 @@ protected:
////static bool lastReadHadEOF = false; ////static bool lastReadHadEOF = false;
static bool operationEnded = false; static bool operationEnded = false;
static DWORD lastInternetStatus; static bool handleClosed = false;
static LPVOID lastlpvStatusInformation;
static DWORD lastStatusInfo; static DWORD lastStatusInfo;
static DWORD lastStatusInfoLength; static DWORD lastStatusInfoLength;
static HINTERNET urlStreamHandle;
// These two may be useful for debugging:
static DWORD lastInternetStatus;
static LPVOID lastlpvStatusInformation;
// Callback for InternetOpenURL() and InternetReadFileEx() // Callback for InternetOpenURL() and InternetReadFileEx()
static void CALLBACK BOINCInternetStatusCallback( static void CALLBACK BOINCInternetStatusCallback(
@ -114,13 +119,24 @@ static void CALLBACK BOINCInternetStatusCallback(
DWORD dwStatusInformationLength DWORD dwStatusInformationLength
) )
{ {
INTERNET_ASYNC_RESULT* res;
lastInternetStatus = dwInternetStatus; lastInternetStatus = dwInternetStatus;
lastlpvStatusInformation = lpvStatusInformation; lastlpvStatusInformation = lpvStatusInformation;
lastStatusInfoLength = dwStatusInformationLength; lastStatusInfoLength = dwStatusInformationLength;
if (lastStatusInfoLength == sizeof(DWORD)) { if (lastStatusInfoLength == sizeof(DWORD)) {
lastStatusInfo = *(DWORD*)lpvStatusInformation; lastStatusInfo = *(DWORD*)lpvStatusInformation;
} else {
lastStatusInfo = 0;
} }
switch (dwInternetStatus) { switch (dwInternetStatus) {
case INTERNET_STATUS_HANDLE_CREATED:
res = (INTERNET_ASYNC_RESULT*)lpvStatusInformation;
urlStreamHandle = (HINTERNET)(res->dwResult);
break;
case INTERNET_STATUS_HANDLE_CLOSING:
handleClosed = true;
break;
case INTERNET_STATUS_REQUEST_COMPLETE: case INTERNET_STATUS_REQUEST_COMPLETE:
operationEnded = true; operationEnded = true;
break; break;
@ -133,6 +149,21 @@ static void CALLBACK BOINCInternetStatusCallback(
} }
static void BOINCCloseInternetHandle(HINTERNET handle) {
if (!handle) return;
// Setting callback should be redundant, but do it for safety
InternetSetStatusCallback(handle, BOINCInternetStatusCallback);
handleClosed = false;
InternetCloseHandle(handle);
while (!handleClosed) {
wxThread::Sleep(20);
wxGetApp().Yield(true);
}
}
HINTERNET wxWinINetURL::GetSessionHandle(bool closeSessionHandle) HINTERNET wxWinINetURL::GetSessionHandle(bool closeSessionHandle)
{ {
// this struct ensures that the session is opened when the // this struct ensures that the session is opened when the
@ -170,15 +201,12 @@ HINTERNET wxWinINetURL::GetSessionHandle(bool closeSessionHandle)
} }
void INetCloseSession() { void INetCloseSession() {
InternetSetStatusCallback(NULL, BOINCInternetStatusCallback); if (m_handle) {
// We can't call BOINCCloseInternetHandle() here
while (m_handle) { // because wxGetApp().Yield() is no longer valid.
BOOL closedOK = InternetCloseHandle(m_handle); InternetSetStatusCallback(m_handle, NULL);
if (closedOK) { InternetCloseHandle(m_handle);
m_handle = NULL; m_handle = NULL;
} else {
wxGetApp().Yield(true);
}
} }
} }
@ -190,14 +218,8 @@ HINTERNET wxWinINetURL::GetSessionHandle(bool closeSessionHandle)
wxASSERT(pDoc); wxASSERT(pDoc);
if (closeSessionHandle) { if (closeSessionHandle) {
while (session.m_handle) { BOINCCloseInternetHandle(session.m_handle);
BOOL closedOK = InternetCloseHandle(session.m_handle); session.m_handle = NULL;
if (closedOK) {
session.m_handle = NULL;
} else{
wxGetApp().Yield(true);
}
}
return 0; return 0;
} }
@ -252,6 +274,7 @@ size_t wxWinINetInputStream::GetSize() const
size_t wxWinINetInputStream::OnSysRead(void *buffer, size_t bufsize) size_t wxWinINetInputStream::OnSysRead(void *buffer, size_t bufsize)
{ {
DWORD bytesread = 0; DWORD bytesread = 0;
DWORD totalbytesread = 0;
DWORD lError = ERROR_SUCCESS; DWORD lError = ERROR_SUCCESS;
BYTE *buf = (BYTE*)buffer; BYTE *buf = (BYTE*)buffer;
DWORD buflen = (DWORD)bufsize; DWORD buflen = (DWORD)bufsize;
@ -269,12 +292,12 @@ size_t wxWinINetInputStream::OnSysRead(void *buffer, size_t bufsize)
SetError(wxSTREAM_READ_ERROR); SetError(wxSTREAM_READ_ERROR);
return 0; return 0;
} }
while (1) { while (1) {
bytesread = 0; bytesread = 0;
success = InternetReadFile(m_hFile, buf, buflen, &bytesread); success = InternetReadFile(m_hFile, buf, buflen, &bytesread);
totalbytesread += bytesread;
if (success) { if (success) {
if ( bytesread == 0 ) { if ( totalbytesread == 0 ) {
SetError(wxSTREAM_EOF); SetError(wxSTREAM_EOF);
} }
break; break;
@ -289,14 +312,15 @@ size_t wxWinINetInputStream::OnSysRead(void *buffer, size_t bufsize)
// will call us again with a fresh empty buffer. // will call us again with a fresh empty buffer.
break; break;
} }
continue; // Read the enxt chunk of data wxThread::Sleep(20);
wxGetApp().Yield(true);
continue; // Read the next chunk of data
} else { } else {
SetError(wxSTREAM_READ_ERROR); SetError(wxSTREAM_READ_ERROR);
break; break;
} }
} }
#if 0 // Possibly useful for debugging #if 0 // Possibly useful for debugging
if ((!success) || (lError != ERROR_SUCCESS)) { if ((!success) || (lError != ERROR_SUCCESS)) {
DWORD iError, bLength = 0; DWORD iError, bLength = 0;
@ -327,7 +351,7 @@ size_t wxWinINetInputStream::OnSysRead(void *buffer, size_t bufsize)
} }
} // End while(1) } // End while(1)
return bytesread; return totalbytesread;
} }
@ -350,7 +374,7 @@ wxWinINetInputStream::~wxWinINetInputStream()
{ {
if ( m_hFile ) if ( m_hFile )
{ {
InternetCloseHandle(m_hFile); BOINCCloseInternetHandle(m_hFile);
m_hFile=0; m_hFile=0;
} }
} }
@ -368,6 +392,8 @@ static bool bAlreadyRunning = false;
wxASSERT(pDoc); wxASSERT(pDoc);
urlStreamHandle = NULL;
if (b_ShuttingDown || (!pDoc->IsConnected())) { if (b_ShuttingDown || (!pDoc->IsConnected())) {
GetSessionHandle(true); // Closes the session handle GetSessionHandle(true); // Closes the session handle
bAlreadyRunning = false; bAlreadyRunning = false;
@ -395,26 +421,25 @@ static bool bAlreadyRunning = false;
double endtimeout = dtime() + dInternetTimeout; double endtimeout = dtime() + dInternetTimeout;
wxLogTrace(wxT("Function Status"), wxT("wxWinINetURL::GetInputStream - Downloading file: '%s'\n"), owner->GetURL().c_str()); wxLogTrace(wxT("Function Status"), wxT("wxWinINetURL::GetInputStream - Downloading file: '%s'\n"), owner->GetURL().c_str());
HINTERNET newStreamHandle = InternetOpenUrl InternetOpenUrl (
( GetSessionHandle(),
GetSessionHandle(), owner->GetURL(),
owner->GetURL(), NULL,
NULL, 0,
0, INTERNET_FLAG_KEEP_CONNECTION |
INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_PASSIVE,
INTERNET_FLAG_PASSIVE, 1
1 );
);
while (!operationEnded) { while (!operationEnded) {
if (b_ShuttingDown || if (b_ShuttingDown ||
(!pDoc->IsConnected()) || (!pDoc->IsConnected()) ||
(dtime() > endtimeout) (dtime() > endtimeout)
) { ) {
GetSessionHandle(true); // Closes the session handle if (urlStreamHandle) {
if (newStreamHandle) { BOINCCloseInternetHandle(urlStreamHandle);
InternetCloseHandle(newStreamHandle); urlStreamHandle = NULL;
newStreamHandle = NULL;
} }
GetSessionHandle(true); // Closes the session handle
if (newStream) { if (newStream) {
delete newStream; delete newStream;
newStream = NULL; newStream = NULL;
@ -424,22 +449,11 @@ static bool bAlreadyRunning = false;
return 0; return 0;
} }
wxThread::Sleep(20);
wxGetApp().Yield(true); wxGetApp().Yield(true);
} }
if ((lastInternetStatus == INTERNET_STATUS_REQUEST_COMPLETE) && if (!urlStreamHandle) {
(lastStatusInfoLength >= sizeof(HINTERNET)) &&
(!b_ShuttingDown)
) {
INTERNET_ASYNC_RESULT* res = (INTERNET_ASYNC_RESULT*)lastlpvStatusInformation;
if (res && !res->dwError) {
newStreamHandle = (HINTERNET)(res->dwResult);
} else {
newStreamHandle = NULL;
}
}
if (!newStreamHandle) {
if (newStream) { if (newStream) {
delete newStream; delete newStream;
newStream = NULL; newStream = NULL;
@ -450,7 +464,7 @@ static bool bAlreadyRunning = false;
return NULL; return NULL;
} }
newStream->Attach(newStreamHandle); newStream->Attach(urlStreamHandle);
dInternetTimeout = STANDARD_INTERNET_TIMEOUT; dInternetTimeout = STANDARD_INTERNET_TIMEOUT;
bAlreadyRunning = false; bAlreadyRunning = false;
@ -510,6 +524,7 @@ bool CBOINCInternetFSHandler::CanOpen(const wxString& location)
{ {
if (b_ShuttingDown) return false; if (b_ShuttingDown) return false;
#if 0
// Check to see if we support the download of the specified file type // Check to see if we support the download of the specified file type
// TODO: We'll need to revisit this policy after the next public release. // TODO: We'll need to revisit this policy after the next public release.
// Either wait for the wxWidgets 3.0 migration, or fix the async file // Either wait for the wxWidgets 3.0 migration, or fix the async file
@ -524,6 +539,7 @@ bool CBOINCInternetFSHandler::CanOpen(const wxString& location)
if (file.GetExt() == wxT("png")) return false; if (file.GetExt() == wxT("png")) return false;
if (file.GetExt() == wxT("tiff")) return false; if (file.GetExt() == wxT("tiff")) return false;
if (file.GetExt() == wxT("jpeg")) return false; if (file.GetExt() == wxT("jpeg")) return false;
#endif
// Regular check based on protocols // Regular check based on protocols
// //