Jacek Caban : urlmon: Use separated variable for InternetQueryDataAvailable to avoid races.
Alexandre Julliard
julliard at winehq.org
Fri Feb 22 14:14:00 CST 2013
Module: wine
Branch: master
Commit: b6a7cc91123f1c78e02472e8839c4727d27b67bd
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b6a7cc91123f1c78e02472e8839c4727d27b67bd
Author: Jacek Caban <jacek at codeweavers.com>
Date: Fri Feb 22 14:13:19 2013 +0100
urlmon: Use separated variable for InternetQueryDataAvailable to avoid races.
---
dlls/urlmon/protocol.c | 55 ++++++++++++++++++++++++++------------------
dlls/urlmon/urlmon_main.h | 1 +
2 files changed, 33 insertions(+), 23 deletions(-)
diff --git a/dlls/urlmon/protocol.c b/dlls/urlmon/protocol.c
index c7c61da..890d013 100644
--- a/dlls/urlmon/protocol.c
+++ b/dlls/urlmon/protocol.c
@@ -349,30 +349,35 @@ HRESULT protocol_continue(Protocol *protocol, PROTOCOLDATA *data)
if(data->pData >= UlongToPtr(BINDSTATUS_DOWNLOADINGDATA)) {
if(!protocol->available_bytes) {
- BOOL res;
-
- /* InternetQueryDataAvailable may immediately fork and perform its asynchronous
- * read, so clear the flag _before_ calling so it does not incorrectly get cleared
- * after the status callback is called */
- protocol->flags &= ~FLAG_REQUEST_COMPLETE;
- res = InternetQueryDataAvailable(protocol->request, &protocol->available_bytes, 0, 0);
- if(res) {
- TRACE("available %u bytes\n", protocol->available_bytes);
- if(!protocol->available_bytes) {
- if(is_start) {
- TRACE("empty file\n");
- all_data_read(protocol);
- }else {
- WARN("unexpected end of file?\n");
- report_result(protocol, INET_E_DOWNLOAD_FAILURE);
+ if(protocol->query_available) {
+ protocol->available_bytes = protocol->query_available;
+ }else {
+ BOOL res;
+
+ /* InternetQueryDataAvailable may immediately fork and perform its asynchronous
+ * read, so clear the flag _before_ calling so it does not incorrectly get cleared
+ * after the status callback is called */
+ protocol->flags &= ~FLAG_REQUEST_COMPLETE;
+ res = InternetQueryDataAvailable(protocol->request, &protocol->query_available, 0, 0);
+ if(res) {
+ TRACE("available %u bytes\n", protocol->query_available);
+ if(!protocol->query_available) {
+ if(is_start) {
+ TRACE("empty file\n");
+ all_data_read(protocol);
+ }else {
+ WARN("unexpected end of file?\n");
+ report_result(protocol, INET_E_DOWNLOAD_FAILURE);
+ }
+ return S_OK;
}
+ protocol->available_bytes = protocol->query_available;
+ }else if(GetLastError() != ERROR_IO_PENDING) {
+ protocol->flags |= FLAG_REQUEST_COMPLETE;
+ WARN("InternetQueryDataAvailable failed: %d\n", GetLastError());
+ report_result(protocol, INET_E_DATA_NOT_AVAILABLE);
return S_OK;
}
- }else if(GetLastError() != ERROR_IO_PENDING) {
- protocol->flags |= FLAG_REQUEST_COMPLETE;
- WARN("InternetQueryDataAvailable failed: %d\n", GetLastError());
- report_result(protocol, INET_E_DATA_NOT_AVAILABLE);
- return S_OK;
}
protocol->flags |= FLAG_REQUEST_COMPLETE;
@@ -421,12 +426,14 @@ HRESULT protocol_read(Protocol *protocol, void *buf, ULONG size, ULONG *read_ret
protocol->current_position += len;
protocol->available_bytes -= len;
+ TRACE("current_position %d, available_bytes %d\n", protocol->current_position, protocol->available_bytes);
+
if(!protocol->available_bytes) {
/* InternetQueryDataAvailable may immediately fork and perform its asynchronous
* read, so clear the flag _before_ calling so it does not incorrectly get cleared
* after the status callback is called */
protocol->flags &= ~FLAG_REQUEST_COMPLETE;
- res = InternetQueryDataAvailable(protocol->request, &protocol->available_bytes, 0, 0);
+ res = InternetQueryDataAvailable(protocol->request, &protocol->query_available, 0, 0);
if(!res) {
if (GetLastError() == ERROR_IO_PENDING) {
hres = E_PENDING;
@@ -438,10 +445,12 @@ HRESULT protocol_read(Protocol *protocol, void *buf, ULONG size, ULONG *read_ret
break;
}
- if(!protocol->available_bytes) {
+ if(!protocol->query_available) {
all_data_read(protocol);
break;
}
+
+ protocol->available_bytes = protocol->query_available;
}
}
diff --git a/dlls/urlmon/urlmon_main.h b/dlls/urlmon/urlmon_main.h
index 01de984..ba23e74 100644
--- a/dlls/urlmon/urlmon_main.h
+++ b/dlls/urlmon/urlmon_main.h
@@ -104,6 +104,7 @@ typedef struct {
ULONG current_position;
ULONG content_length;
ULONG available_bytes;
+ ULONG query_available;
IStream *post_stream;
More information about the wine-cvs
mailing list