Module: wine Branch: master Commit: a546e8acaadfa67457dd31da9610bbeeb233047c URL: http://source.winehq.org/git/wine.git/?a=commit;h=a546e8acaadfa67457dd31da96...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Mar 9 18:20:02 2017 +0100
wininet: Reimplemented InternetQueryDataAvailable on top of async_read.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/wininet/http.c | 78 ++++++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 37 deletions(-)
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index c9119f3..3e0bd97 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -3285,56 +3285,60 @@ static DWORD HTTPREQ_ReadFile(object_header_t *hdr, void *buffer, DWORD size, DW return res; }
-typedef struct { - task_header_t hdr; - DWORD *ret_size; -} http_data_available_task_t; - -static void AsyncQueryDataAvailableProc(task_header_t *hdr) -{ - http_data_available_task_t *task = (http_data_available_task_t*)hdr; - - HTTP_ReceiveRequestData((http_request_t*)task->hdr.hdr, FALSE, task->ret_size); -} - static DWORD HTTPREQ_QueryDataAvailable(object_header_t *hdr, DWORD *available, DWORD flags, DWORD_PTR ctx) { http_request_t *req = (http_request_t*)hdr; + DWORD res = ERROR_SUCCESS, avail = 0, error = ERROR_SUCCESS; + BOOL allow_blocking, notify_received = FALSE;
TRACE("(%p %p %x %lx)\n", req, available, flags, ctx);
- if (req->session->appInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC) - { - http_data_available_task_t *task; + if (flags & ~(IRF_ASYNC|IRF_NO_WAIT)) + FIXME("these dwFlags aren't implemented: 0x%x\n", flags & ~(IRF_ASYNC|IRF_NO_WAIT));
- /* never wait, if we can't enter the section we queue an async request right away */ - if (TryEnterCriticalSection( &req->read_section )) - { - refill_read_buffer(req, BLOCKING_DISALLOW, NULL); - if ((*available = get_avail_data( req ))) goto done; - if (end_of_read_data( req )) goto done; - LeaveCriticalSection( &req->read_section ); - } + *available = 0; + allow_blocking = !(req->session->appInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC);
- task = alloc_async_task(&req->hdr, AsyncQueryDataAvailableProc, sizeof(*task)); - task->ret_size = available; - INTERNET_AsyncCall(&task->hdr); - return ERROR_IO_PENDING; - } + if(allow_blocking || TryEnterCriticalSection(&req->read_section)) { + if(allow_blocking) + EnterCriticalSection(&req->read_section); + if(hdr->dwError == ERROR_SUCCESS) + hdr->dwError = INTERNET_HANDLE_IN_USE; + else if(hdr->dwError == INTERNET_HANDLE_IN_USE) + hdr->dwError = ERROR_INTERNET_INTERNAL_ERROR;
- EnterCriticalSection( &req->read_section ); + avail = req->read_size;
- if (!(*available = get_avail_data( req )) && !end_of_read_data( req )) - { - refill_read_buffer( req, BLOCKING_ALLOW, NULL ); - *available = get_avail_data( req ); + if(!avail && !end_of_read_data(req)) { + LeaveCriticalSection(&req->read_section); + INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0); + EnterCriticalSection( &req->read_section ); + notify_received = TRUE; + + res = refill_read_buffer(req, allow_blocking ? BLOCKING_ALLOW : BLOCKING_DISALLOW, &avail); + } + + if(hdr->dwError == INTERNET_HANDLE_IN_USE) + hdr->dwError = ERROR_SUCCESS; + else + error = hdr->dwError; + + LeaveCriticalSection( &req->read_section ); + }else { + res = WSAEWOULDBLOCK; }
-done: - LeaveCriticalSection( &req->read_section ); + if(res == WSAEWOULDBLOCK) + return async_read(req, NULL, 0, 0, available);
- TRACE( "returning %u\n", *available ); - return ERROR_SUCCESS; + if (res != ERROR_SUCCESS) + return res; + + *available = avail; + if(notify_received) + INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_RESPONSE_RECEIVED, + &avail, sizeof(avail)); + return error; }
static DWORD HTTPREQ_LockRequestFile(object_header_t *hdr, req_file_t **ret)