Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
381c034b
Commit
381c034b
authored
Oct 09, 2015
by
Sebastian Lackner
Committed by
Alexandre Julliard
Oct 09, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Wait_thread_proc should not terminate on user APC.
Signed-off-by:
Sebastian Lackner
<
sebastian@fds-team.de
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
e37cdbbc
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
67 additions
and
3 deletions
+67
-3
threadpool.c
dlls/ntdll/tests/threadpool.c
+66
-2
threadpool.c
dlls/ntdll/threadpool.c
+1
-1
No files found.
dlls/ntdll/tests/threadpool.c
View file @
381c034b
...
@@ -148,6 +148,7 @@ struct rtl_wait_info
...
@@ -148,6 +148,7 @@ struct rtl_wait_info
HANDLE
semaphore1
;
HANDLE
semaphore1
;
HANDLE
semaphore2
;
HANDLE
semaphore2
;
DWORD
wait_result
;
DWORD
wait_result
;
DWORD
threadid
;
LONG
userdata
;
LONG
userdata
;
};
};
...
@@ -162,6 +163,7 @@ static void CALLBACK rtl_wait_cb(void *userdata, BOOLEAN timeout)
...
@@ -162,6 +163,7 @@ static void CALLBACK rtl_wait_cb(void *userdata, BOOLEAN timeout)
InterlockedIncrement
(
&
info
->
userdata
);
InterlockedIncrement
(
&
info
->
userdata
);
else
else
InterlockedExchangeAdd
(
&
info
->
userdata
,
0x10000
);
InterlockedExchangeAdd
(
&
info
->
userdata
,
0x10000
);
info
->
threadid
=
GetCurrentThreadId
();
ReleaseSemaphore
(
info
->
semaphore1
,
1
,
NULL
);
ReleaseSemaphore
(
info
->
semaphore1
,
1
,
NULL
);
if
(
info
->
semaphore2
)
if
(
info
->
semaphore2
)
...
@@ -172,14 +174,22 @@ static void CALLBACK rtl_wait_cb(void *userdata, BOOLEAN timeout)
...
@@ -172,14 +174,22 @@ static void CALLBACK rtl_wait_cb(void *userdata, BOOLEAN timeout)
}
}
}
}
static
HANDLE
rtl_wait_apc_semaphore
;
static
void
CALLBACK
rtl_wait_apc_cb
(
ULONG_PTR
userdata
)
{
trace
(
"Running rtl_wait_apc callback
\n
"
);
if
(
rtl_wait_apc_semaphore
)
ReleaseSemaphore
(
rtl_wait_apc_semaphore
,
1
,
NULL
);
}
static
void
test_RtlRegisterWait
(
void
)
static
void
test_RtlRegisterWait
(
void
)
{
{
HANDLE
wait1
,
event
,
thread
;
struct
rtl_wait_info
info
;
struct
rtl_wait_info
info
;
HANDLE
semaphores
[
2
];
HANDLE
semaphores
[
2
];
NTSTATUS
status
;
NTSTATUS
status
;
DWORD
result
;
DWORD
result
;
HANDLE
wait1
;
HANDLE
event
;
semaphores
[
0
]
=
CreateSemaphoreW
(
NULL
,
0
,
2
,
NULL
);
semaphores
[
0
]
=
CreateSemaphoreW
(
NULL
,
0
,
2
,
NULL
);
ok
(
semaphores
[
0
]
!=
NULL
,
"failed to create semaphore
\n
"
);
ok
(
semaphores
[
0
]
!=
NULL
,
"failed to create semaphore
\n
"
);
...
@@ -270,6 +280,60 @@ static void test_RtlRegisterWait(void)
...
@@ -270,6 +280,60 @@ static void test_RtlRegisterWait(void)
status
=
RtlDeregisterWait
(
wait1
);
status
=
RtlDeregisterWait
(
wait1
);
ok
(
!
status
,
"RtlDeregisterWait failed with status %x
\n
"
,
status
);
ok
(
!
status
,
"RtlDeregisterWait failed with status %x
\n
"
,
status
);
/* test for IO threads */
info
.
userdata
=
0
;
info
.
threadid
=
0
;
status
=
RtlRegisterWait
(
&
wait1
,
semaphores
[
1
],
rtl_wait_cb
,
&
info
,
INFINITE
,
WT_EXECUTEINIOTHREAD
);
ok
(
!
status
,
"RtlRegisterWait failed with status %x
\n
"
,
status
);
ReleaseSemaphore
(
semaphores
[
1
],
1
,
NULL
);
result
=
WaitForSingleObject
(
semaphores
[
0
],
100
);
ok
(
result
==
WAIT_OBJECT_0
,
"WaitForSingleObject returned %u
\n
"
,
result
);
ok
(
info
.
userdata
==
1
,
"expected info.userdata = 1, got %u
\n
"
,
info
.
userdata
);
ok
(
info
.
threadid
!=
0
,
"expected info.threadid != 0, got %u
\n
"
,
info
.
threadid
);
thread
=
OpenThread
(
THREAD_SET_CONTEXT
,
FALSE
,
info
.
threadid
);
ok
(
thread
!=
NULL
,
"OpenThread failed with %u
\n
"
,
GetLastError
());
rtl_wait_apc_semaphore
=
semaphores
[
0
];
result
=
QueueUserAPC
(
rtl_wait_apc_cb
,
thread
,
0
);
ok
(
result
!=
0
,
"QueueUserAPC failed with %u
\n
"
,
GetLastError
());
result
=
WaitForSingleObject
(
semaphores
[
0
],
200
);
ok
(
result
==
WAIT_OBJECT_0
,
"WaitForSingleObject returned %u
\n
"
,
result
);
rtl_wait_apc_semaphore
=
0
;
CloseHandle
(
thread
);
ReleaseSemaphore
(
semaphores
[
1
],
1
,
NULL
);
result
=
WaitForSingleObject
(
semaphores
[
0
],
100
);
ok
(
result
==
WAIT_OBJECT_0
,
"WaitForSingleObject returned %u
\n
"
,
result
);
ok
(
info
.
userdata
==
2
,
"expected info.userdata = 2, got %u
\n
"
,
info
.
userdata
);
Sleep
(
50
);
status
=
RtlDeregisterWait
(
wait1
);
ok
(
!
status
,
"RtlDeregisterWait failed with status %x
\n
"
,
status
);
info
.
userdata
=
0
;
info
.
threadid
=
0
;
status
=
RtlRegisterWait
(
&
wait1
,
semaphores
[
1
],
rtl_wait_cb
,
&
info
,
INFINITE
,
WT_EXECUTEDEFAULT
);
ok
(
!
status
,
"RtlRegisterWait failed with status %x
\n
"
,
status
);
ReleaseSemaphore
(
semaphores
[
1
],
1
,
NULL
);
result
=
WaitForSingleObject
(
semaphores
[
0
],
100
);
ok
(
result
==
WAIT_OBJECT_0
,
"WaitForSingleObject returned %u
\n
"
,
result
);
ok
(
info
.
userdata
==
1
,
"expected info.userdata = 1, got %u
\n
"
,
info
.
userdata
);
ok
(
info
.
threadid
!=
0
,
"expected info.threadid != 0, got %u
\n
"
,
info
.
threadid
);
thread
=
OpenThread
(
THREAD_SET_CONTEXT
,
FALSE
,
info
.
threadid
);
ok
(
thread
!=
NULL
,
"OpenThread failed with %u
\n
"
,
GetLastError
());
rtl_wait_apc_semaphore
=
semaphores
[
0
];
result
=
QueueUserAPC
(
rtl_wait_apc_cb
,
thread
,
0
);
ok
(
result
!=
0
,
"QueueUserAPC failed with %u
\n
"
,
GetLastError
());
result
=
WaitForSingleObject
(
semaphores
[
0
],
200
);
ok
(
result
==
WAIT_TIMEOUT
||
broken
(
result
==
WAIT_OBJECT_0
)
/* >= Win Vista */
,
"WaitForSingleObject returned %u
\n
"
,
result
);
rtl_wait_apc_semaphore
=
0
;
CloseHandle
(
thread
);
ReleaseSemaphore
(
semaphores
[
1
],
1
,
NULL
);
result
=
WaitForSingleObject
(
semaphores
[
0
],
100
);
ok
(
result
==
WAIT_OBJECT_0
,
"WaitForSingleObject returned %u
\n
"
,
result
);
ok
(
info
.
userdata
==
2
,
"expected info.userdata = 2, got %u
\n
"
,
info
.
userdata
);
Sleep
(
50
);
status
=
RtlDeregisterWait
(
wait1
);
ok
(
!
status
,
"RtlDeregisterWait failed with status %x
\n
"
,
status
);
/* test RtlDeregisterWaitEx before wait expired */
/* test RtlDeregisterWaitEx before wait expired */
info
.
userdata
=
0
;
info
.
userdata
=
0
;
status
=
RtlRegisterWait
(
&
wait1
,
semaphores
[
1
],
rtl_wait_cb
,
&
info
,
INFINITE
,
WT_EXECUTEDEFAULT
);
status
=
RtlRegisterWait
(
&
wait1
,
semaphores
[
1
],
rtl_wait_cb
,
&
info
,
INFINITE
,
WT_EXECUTEDEFAULT
);
...
...
dlls/ntdll/threadpool.c
View file @
381c034b
...
@@ -537,7 +537,7 @@ static DWORD CALLBACK wait_thread_proc(LPVOID Arg)
...
@@ -537,7 +537,7 @@ static DWORD CALLBACK wait_thread_proc(LPVOID Arg)
if
(
wait_work_item
->
Flags
&
WT_EXECUTEONLYONCE
)
if
(
wait_work_item
->
Flags
&
WT_EXECUTEONLYONCE
)
break
;
break
;
}
}
else
else
if
(
status
!=
STATUS_USER_APC
)
break
;
break
;
}
}
...
...
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