Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
d6c9c984
Commit
d6c9c984
authored
Feb 16, 2015
by
Hans Leidekker
Committed by
Alexandre Julliard
Feb 16, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winhttp: Implement a task queue for asynchronous requests.
This ensures that asynchronous calls are completed in the right order.
parent
8c158c1e
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
96 additions
and
10 deletions
+96
-10
request.c
dlls/winhttp/request.c
+74
-7
session.c
dlls/winhttp/session.c
+16
-3
winhttp_private.h
dlls/winhttp/winhttp_private.h
+6
-0
No files found.
dlls/winhttp/request.c
View file @
d6c9c984
...
...
@@ -178,20 +178,87 @@ static const WCHAR *attribute_table[] =
NULL
/* WINHTTP_QUERY_PASSPORT_CONFIG = 78 */
};
static
DWORD
CALLBACK
task_thread
(
LPVOID
param
)
static
task_header_t
*
dequeue_task
(
request_t
*
request
)
{
task_header_t
*
task
=
param
;
task_header_t
*
task
;
task
->
proc
(
task
);
EnterCriticalSection
(
&
request
->
task_cs
);
TRACE
(
"%u tasks queued
\n
"
,
list_count
(
&
request
->
task_queue
));
task
=
LIST_ENTRY
(
list_head
(
&
request
->
task_queue
),
task_header_t
,
entry
);
if
(
task
)
list_remove
(
&
task
->
entry
);
LeaveCriticalSection
(
&
request
->
task_cs
);
release_object
(
&
task
->
request
->
hdr
);
heap_free
(
task
);
return
ERROR_SUCCESS
;
TRACE
(
"returning task %p
\n
"
,
task
);
return
task
;
}
static
DWORD
CALLBACK
task_proc
(
LPVOID
param
)
{
request_t
*
request
=
param
;
HANDLE
handles
[
2
];
handles
[
0
]
=
request
->
task_wait
;
handles
[
1
]
=
request
->
task_cancel
;
for
(;;)
{
DWORD
err
=
WaitForMultipleObjects
(
2
,
handles
,
FALSE
,
INFINITE
);
switch
(
err
)
{
case
WAIT_OBJECT_0
:
{
task_header_t
*
task
;
while
((
task
=
dequeue_task
(
request
)))
{
task
->
proc
(
task
);
release_object
(
&
task
->
request
->
hdr
);
heap_free
(
task
);
}
break
;
}
case
WAIT_OBJECT_0
+
1
:
TRACE
(
"exiting
\n
"
);
return
0
;
default:
ERR
(
"wait failed %u (%u)
\n
"
,
err
,
GetLastError
());
break
;
}
}
return
0
;
}
static
BOOL
queue_task
(
task_header_t
*
task
)
{
return
QueueUserWorkItem
(
task_thread
,
task
,
WT_EXECUTELONGFUNCTION
);
request_t
*
request
=
task
->
request
;
if
(
!
request
->
task_thread
)
{
if
(
!
(
request
->
task_wait
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
)))
return
FALSE
;
if
(
!
(
request
->
task_cancel
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
)))
{
CloseHandle
(
request
->
task_wait
);
request
->
task_wait
=
NULL
;
return
FALSE
;
}
if
(
!
(
request
->
task_thread
=
CreateThread
(
NULL
,
0
,
task_proc
,
request
,
0
,
NULL
)))
{
CloseHandle
(
request
->
task_wait
);
request
->
task_wait
=
NULL
;
CloseHandle
(
request
->
task_cancel
);
request
->
task_cancel
=
NULL
;
return
FALSE
;
}
InitializeCriticalSection
(
&
request
->
task_cs
);
request
->
task_cs
.
DebugInfo
->
Spare
[
0
]
=
(
DWORD_PTR
)(
__FILE__
": request.task_cs"
);
}
EnterCriticalSection
(
&
request
->
task_cs
);
TRACE
(
"queueing task %p
\n
"
,
task
);
list_add_tail
(
&
request
->
task_queue
,
&
task
->
entry
);
LeaveCriticalSection
(
&
request
->
task_cs
);
SetEvent
(
request
->
task_wait
);
return
TRUE
;
}
static
void
free_header
(
header_t
*
header
)
...
...
dlls/winhttp/session.c
View file @
d6c9c984
...
...
@@ -70,9 +70,12 @@ DWORD get_last_error( void )
void
send_callback
(
object_header_t
*
hdr
,
DWORD
status
,
LPVOID
info
,
DWORD
buflen
)
{
TRACE
(
"%p, 0x%08x, %p, %u
\n
"
,
hdr
,
status
,
info
,
buflen
);
if
(
hdr
->
callback
&&
(
hdr
->
notify_mask
&
status
))
hdr
->
callback
(
hdr
->
handle
,
hdr
->
context
,
status
,
info
,
buflen
);
if
(
hdr
->
callback
&&
(
hdr
->
notify_mask
&
status
))
{
TRACE
(
"%p, 0x%08x, %p, %u
\n
"
,
hdr
,
status
,
info
,
buflen
);
hdr
->
callback
(
hdr
->
handle
,
hdr
->
context
,
status
,
info
,
buflen
);
TRACE
(
"returning from 0x%08x callback
\n
"
,
status
);
}
}
/***********************************************************************
...
...
@@ -556,6 +559,15 @@ static void request_destroy( object_header_t *hdr )
TRACE
(
"%p
\n
"
,
request
);
if
(
request
->
task_thread
)
{
SetEvent
(
request
->
task_cancel
);
WaitForSingleObject
(
request
->
task_thread
,
INFINITE
);
CloseHandle
(
request
->
task_thread
);
CloseHandle
(
request
->
task_cancel
);
CloseHandle
(
request
->
task_wait
);
DeleteCriticalSection
(
&
request
->
task_cs
);
}
release_object
(
&
request
->
connect
->
hdr
);
destroy_authinfo
(
request
->
authinfo
);
...
...
@@ -1057,6 +1069,7 @@ HINTERNET WINAPI WinHttpOpenRequest( HINTERNET hconnect, LPCWSTR verb, LPCWSTR o
request
->
hdr
.
context
=
connect
->
hdr
.
context
;
request
->
hdr
.
redirect_policy
=
connect
->
hdr
.
redirect_policy
;
list_init
(
&
request
->
hdr
.
children
);
list_init
(
&
request
->
task_queue
);
addref_object
(
&
connect
->
hdr
);
request
->
connect
=
connect
;
...
...
dlls/winhttp/winhttp_private.h
View file @
d6c9c984
...
...
@@ -201,12 +201,18 @@ typedef struct
DWORD
num_accept_types
;
struct
authinfo
*
authinfo
;
struct
authinfo
*
proxy_authinfo
;
HANDLE
task_wait
;
HANDLE
task_cancel
;
HANDLE
task_thread
;
struct
list
task_queue
;
CRITICAL_SECTION
task_cs
;
}
request_t
;
typedef
struct
_task_header_t
task_header_t
;
struct
_task_header_t
{
struct
list
entry
;
request_t
*
request
;
void
(
*
proc
)(
task_header_t
*
);
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment