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
9dfa1022
Commit
9dfa1022
authored
Aug 18, 2016
by
Sebastian Lackner
Committed by
Alexandre Julliard
Aug 18, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
services: Use threadpool API instead of custom wait implementation.
Signed-off-by:
Sebastian Lackner
<
sebastian@fds-team.de
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
6fc42341
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
66 additions
and
131 deletions
+66
-131
winbase.h
include/winbase.h
+6
-0
rpc.c
programs/services/rpc.c
+53
-124
services.c
programs/services/services.c
+5
-4
services.h
programs/services/services.h
+2
-3
No files found.
include/winbase.h
View file @
9dfa1022
...
...
@@ -1710,6 +1710,9 @@ WINADVAPI BOOL WINAPI ClearEventLogW(HANDLE,LPCWSTR);
WINADVAPI
BOOL
WINAPI
CloseEventLog
(
HANDLE
);
WINBASEAPI
BOOL
WINAPI
CloseHandle
(
HANDLE
);
WINBASEAPI
VOID
WINAPI
CloseThreadpool
(
PTP_POOL
);
WINBASEAPI
VOID
WINAPI
CloseThreadpoolCleanupGroup
(
PTP_CLEANUP_GROUP
);
WINBASEAPI
VOID
WINAPI
CloseThreadpoolCleanupGroupMembers
(
PTP_CLEANUP_GROUP
,
BOOL
,
PVOID
);
WINBASEAPI
VOID
WINAPI
CloseThreadpoolWait
(
PTP_WAIT
);
WINBASEAPI
VOID
WINAPI
CloseThreadpoolWork
(
PTP_WORK
);
WINBASEAPI
BOOL
WINAPI
CommConfigDialogA
(
LPCSTR
,
HWND
,
LPCOMMCONFIG
);
WINBASEAPI
BOOL
WINAPI
CommConfigDialogW
(
LPCWSTR
,
HWND
,
LPCOMMCONFIG
);
...
...
@@ -1775,6 +1778,8 @@ WINADVAPI BOOL WINAPI CreatePrivateObjectSecurity(PSECURITY_DESCRIPTOR,P
WINADVAPI
BOOL
WINAPI
CreatePrivateObjectSecurityEx
(
PSECURITY_DESCRIPTOR
,
PSECURITY_DESCRIPTOR
,
PSECURITY_DESCRIPTOR
*
,
GUID
*
,
BOOL
,
ULONG
,
HANDLE
,
PGENERIC_MAPPING
);
WINADVAPI
BOOL
WINAPI
CreatePrivateObjectSecurityWithMultipleInheritance
(
PSECURITY_DESCRIPTOR
,
PSECURITY_DESCRIPTOR
,
PSECURITY_DESCRIPTOR
*
,
GUID
**
,
ULONG
,
BOOL
,
ULONG
,
HANDLE
,
PGENERIC_MAPPING
);
WINBASEAPI
PTP_POOL
WINAPI
CreateThreadpool
(
PVOID
);
WINBASEAPI
PTP_CLEANUP_GROUP
WINAPI
CreateThreadpoolCleanupGroup
(
void
);
WINBASEAPI
PTP_WAIT
WINAPI
CreateThreadpoolWait
(
PTP_WAIT_CALLBACK
,
PVOID
,
PTP_CALLBACK_ENVIRON
);
WINBASEAPI
PTP_WORK
WINAPI
CreateThreadpoolWork
(
PTP_WORK_CALLBACK
,
PVOID
,
PTP_CALLBACK_ENVIRON
);
WINBASEAPI
BOOL
WINAPI
CreateProcessA
(
LPCSTR
,
LPSTR
,
LPSECURITY_ATTRIBUTES
,
LPSECURITY_ATTRIBUTES
,
BOOL
,
DWORD
,
LPVOID
,
LPCSTR
,
LPSTARTUPINFOA
,
LPPROCESS_INFORMATION
);
WINBASEAPI
BOOL
WINAPI
CreateProcessW
(
LPCWSTR
,
LPWSTR
,
LPSECURITY_ATTRIBUTES
,
LPSECURITY_ATTRIBUTES
,
BOOL
,
DWORD
,
LPVOID
,
LPCWSTR
,
LPSTARTUPINFOW
,
LPPROCESS_INFORMATION
);
...
...
@@ -2510,6 +2515,7 @@ WINBASEAPI DWORD WINAPI SetThreadIdealProcessor(HANDLE,DWORD);
WINBASEAPI
BOOL
WINAPI
SetThreadPriority
(
HANDLE
,
INT
);
WINBASEAPI
BOOL
WINAPI
SetThreadPriorityBoost
(
HANDLE
,
BOOL
);
WINADVAPI
BOOL
WINAPI
SetThreadToken
(
PHANDLE
,
HANDLE
);
WINBASEAPI
VOID
WINAPI
SetThreadpoolWait
(
PTP_WAIT
,
HANDLE
,
FILETIME
*
);
WINBASEAPI
HANDLE
WINAPI
SetTimerQueueTimer
(
HANDLE
,
WAITORTIMERCALLBACK
,
PVOID
,
DWORD
,
DWORD
,
BOOL
);
WINBASEAPI
BOOL
WINAPI
SetTimeZoneInformation
(
const
TIME_ZONE_INFORMATION
*
);
WINADVAPI
BOOL
WINAPI
SetTokenInformation
(
HANDLE
,
TOKEN_INFORMATION_CLASS
,
LPVOID
,
DWORD
);
...
...
programs/services/rpc.c
View file @
9dfa1022
...
...
@@ -85,46 +85,51 @@ struct sc_lock
struct
scmdatabase
*
db
;
};
static
HANDLE
timeout_queue_event
;
static
CRITICAL_SECTION
timeout_queue_cs
;
static
CRITICAL_SECTION_DEBUG
timeout_queue_cs_debug
=
static
CRITICAL_SECTION
shutdown_cs
;
static
CRITICAL_SECTION_DEBUG
critsect_debug
=
{
0
,
0
,
&
timeout_queue
_cs
,
{
&
timeout_queue_cs_debug
.
ProcessLocksList
,
&
timeout_queue_cs
_debug
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": timeout_queue
_cs"
)
}
0
,
0
,
&
shutdown
_cs
,
{
&
critsect_debug
.
ProcessLocksList
,
&
critsect
_debug
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": shutdown
_cs"
)
}
};
static
CRITICAL_SECTION
timeout_queue_cs
=
{
&
timeout_queue_cs_debug
,
-
1
,
0
,
0
,
0
,
0
};
static
struct
list
timeout_queue
=
LIST_INIT
(
timeout_queue
);
struct
timeout_queue_elem
{
struct
list
entry
;
static
CRITICAL_SECTION
shutdown_cs
=
{
&
critsect_debug
,
-
1
,
0
,
0
,
0
,
0
};
static
BOOL
service_shutdown
;
FILETIME
time
;
struct
process_entry
*
process
;
};
static
PTP_CLEANUP_GROUP
cleanup_group
;
HANDLE
exit_event
;
static
void
terminate_after_timeout
(
struct
process_entry
*
process
,
DWORD
timeout
)
static
void
CALLBACK
terminate_callback
(
TP_CALLBACK_INSTANCE
*
instance
,
void
*
context
,
TP_WAIT
*
wait
,
TP_WAIT_RESULT
result
)
{
struct
timeout_queue_elem
*
elem
;
ULARGE_INTEGER
time
;
struct
process_entry
*
process
=
context
;
if
(
result
==
WAIT_TIMEOUT
)
process_terminate
(
process
);
release_process
(
process
);
if
(
!
(
elem
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
elem
))))
return
;
/* synchronize with CloseThreadpoolCleanupGroupMembers */
EnterCriticalSection
(
&
shutdown_cs
);
if
(
!
service_shutdown
)
CloseThreadpoolWait
(
wait
);
LeaveCriticalSection
(
&
shutdown_cs
);
}
elem
->
process
=
grab_process
(
process
);
static
void
terminate_after_timeout
(
struct
process_entry
*
process
,
DWORD
timeout
)
{
TP_CALLBACK_ENVIRON
environment
;
LARGE_INTEGER
timestamp
;
TP_WAIT
*
wait
;
FILETIME
ft
;
GetSystemTimeAsFileTime
(
&
elem
->
time
);
time
.
u
.
LowPart
=
elem
->
time
.
dwLowDateTime
;
time
.
u
.
HighPart
=
elem
->
time
.
dwHighDateTime
;
time
.
QuadPart
+=
(
ULONGLONG
)
timeout
*
10000
;
elem
->
time
.
dwLowDateTime
=
time
.
u
.
LowPart
;
elem
->
time
.
dwHighDateTime
=
time
.
u
.
HighPart
;
memset
(
&
environment
,
0
,
sizeof
(
environment
));
environment
.
Version
=
1
;
environment
.
CleanupGroup
=
cleanup_group
;
EnterCriticalSection
(
&
timeout_queue_cs
)
;
list_add_head
(
&
timeout_queue
,
&
elem
->
entry
)
;
LeaveCriticalSection
(
&
timeout_queue_cs
)
;
timestamp
.
QuadPart
=
(
ULONGLONG
)
timeout
*
-
10000
;
ft
.
dwLowDateTime
=
timestamp
.
u
.
LowPart
;
ft
.
dwHighDateTime
=
timestamp
.
u
.
HighPart
;
SetEvent
(
timeout_queue_event
);
if
((
wait
=
CreateThreadpoolWait
(
terminate_callback
,
grab_process
(
process
),
&
environment
)))
SetThreadpoolWait
(
wait
,
process
->
process
,
&
ft
);
else
release_process
(
process
);
}
static
void
free_service_strings
(
struct
service_entry
*
old
,
struct
service_entry
*
new
)
...
...
@@ -1876,6 +1881,12 @@ DWORD RPC_Init(void)
WCHAR
endpoint
[]
=
SVCCTL_ENDPOINT
;
DWORD
err
;
if
(
!
(
cleanup_group
=
CreateThreadpoolCleanupGroup
()))
{
WINE_ERR
(
"CreateThreadpoolCleanupGroup failed with error %u
\n
"
,
GetLastError
());
return
GetLastError
();
}
if
((
err
=
RpcServerUseProtseqEpW
(
transport
,
0
,
endpoint
,
NULL
))
!=
ERROR_SUCCESS
)
{
WINE_ERR
(
"RpcServerUseProtseq failed with error %u
\n
"
,
err
);
...
...
@@ -1893,106 +1904,24 @@ DWORD RPC_Init(void)
WINE_ERR
(
"RpcServerListen failed with error %u
\n
"
,
err
);
return
err
;
}
exit_event
=
__wine_make_process_system
();
return
ERROR_SUCCESS
;
}
DWORD
events_lo
op
(
void
)
void
RPC_St
op
(
void
)
{
struct
timeout_queue_elem
*
iter
,
*
iter_safe
;
DWORD
err
;
HANDLE
wait_handles
[
MAXIMUM_WAIT_OBJECTS
];
DWORD
timeout
=
INFINITE
;
wait_handles
[
0
]
=
__wine_make_process_system
();
wait_handles
[
1
]
=
CreateEventW
(
NULL
,
FALSE
,
FALSE
,
NULL
);
timeout_queue_event
=
wait_handles
[
1
];
SetEvent
(
g_hStartedEvent
);
WINE_TRACE
(
"Entered main loop
\n
"
);
do
{
DWORD
num_handles
=
2
;
/* monitor tracked process handles for process end */
EnterCriticalSection
(
&
timeout_queue_cs
);
LIST_FOR_EACH_ENTRY
(
iter
,
&
timeout_queue
,
struct
timeout_queue_elem
,
entry
)
{
if
(
num_handles
==
MAXIMUM_WAIT_OBJECTS
){
WINE_TRACE
(
"Exceeded maximum wait object count
\n
"
);
break
;
}
wait_handles
[
num_handles
]
=
iter
->
process
->
process
;
num_handles
++
;
}
LeaveCriticalSection
(
&
timeout_queue_cs
);
err
=
WaitForMultipleObjects
(
num_handles
,
wait_handles
,
FALSE
,
timeout
);
WINE_TRACE
(
"Wait returned %d
\n
"
,
err
);
if
(
err
>
WAIT_OBJECT_0
||
err
==
WAIT_TIMEOUT
)
{
FILETIME
cur_time
;
ULARGE_INTEGER
time
;
DWORD
idx
=
0
;
GetSystemTimeAsFileTime
(
&
cur_time
);
time
.
u
.
LowPart
=
cur_time
.
dwLowDateTime
;
time
.
u
.
HighPart
=
cur_time
.
dwHighDateTime
;
EnterCriticalSection
(
&
timeout_queue_cs
);
timeout
=
INFINITE
;
LIST_FOR_EACH_ENTRY_SAFE
(
iter
,
iter_safe
,
&
timeout_queue
,
struct
timeout_queue_elem
,
entry
)
{
if
(
CompareFileTime
(
&
cur_time
,
&
iter
->
time
)
>=
0
||
(
err
>
WAIT_OBJECT_0
+
1
&&
idx
==
err
-
WAIT_OBJECT_0
-
2
))
{
LeaveCriticalSection
(
&
timeout_queue_cs
);
process_terminate
(
iter
->
process
);
EnterCriticalSection
(
&
timeout_queue_cs
);
release_process
(
iter
->
process
);
list_remove
(
&
iter
->
entry
);
HeapFree
(
GetProcessHeap
(),
0
,
iter
);
}
else
{
ULARGE_INTEGER
time_diff
;
time_diff
.
u
.
LowPart
=
iter
->
time
.
dwLowDateTime
;
time_diff
.
u
.
HighPart
=
iter
->
time
.
dwHighDateTime
;
time_diff
.
QuadPart
=
(
time_diff
.
QuadPart
-
time
.
QuadPart
)
/
10000
;
if
(
time_diff
.
QuadPart
<
timeout
)
timeout
=
time_diff
.
QuadPart
;
}
idx
++
;
}
LeaveCriticalSection
(
&
timeout_queue_cs
);
RpcMgmtStopServerListening
(
NULL
);
RpcServerUnregisterIf
(
svcctl_v2_0_s_ifspec
,
NULL
,
TRUE
);
if
(
timeout
!=
INFINITE
)
timeout
+=
1000
;
}
}
while
(
err
!=
WAIT_OBJECT_0
);
/* synchronize with CloseThreadpoolWait */
EnterCriticalSection
(
&
shutdown_cs
)
;
service_shutdown
=
TRUE
;
LeaveCriticalSection
(
&
shutdown_cs
);
WINE_TRACE
(
"Object signaled - wine shutdown
\n
"
);
EnterCriticalSection
(
&
timeout_queue_cs
);
LIST_FOR_EACH_ENTRY_SAFE
(
iter
,
iter_safe
,
&
timeout_queue
,
struct
timeout_queue_elem
,
entry
)
{
LeaveCriticalSection
(
&
timeout_queue_cs
);
process_terminate
(
iter
->
process
);
EnterCriticalSection
(
&
timeout_queue_cs
);
release_process
(
iter
->
process
);
list_remove
(
&
iter
->
entry
);
HeapFree
(
GetProcessHeap
(),
0
,
iter
);
}
LeaveCriticalSection
(
&
timeout_queue_cs
);
CloseHandle
(
wait_handles
[
0
]);
CloseHandle
(
wait_handles
[
1
]);
return
ERROR_SUCCESS
;
CloseThreadpoolCleanupGroupMembers
(
cleanup_group
,
TRUE
,
NULL
);
CloseThreadpoolCleanupGroup
(
cleanup_group
);
CloseHandle
(
exit_event
);
}
void
__RPC_USER
SC_RPC_HANDLE_rundown
(
SC_RPC_HANDLE
handle
)
...
...
programs/services/services.c
View file @
9dfa1022
...
...
@@ -36,7 +36,6 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
service
);
HANDLE
g_hStartedEvent
;
struct
scmdatabase
*
active_database
;
DWORD
service_pipe_timeout
=
10000
;
...
...
@@ -990,10 +989,10 @@ int main(int argc, char *argv[])
'C'
,
'o'
,
'n'
,
't'
,
'r'
,
'o'
,
'l'
,
'\\'
,
'S'
,
'e'
,
'r'
,
'v'
,
'i'
,
'c'
,
'e'
,
'C'
,
'u'
,
'r'
,
'r'
,
'e'
,
'n'
,
't'
,
0
};
static
const
WCHAR
svcctl_started_event
[]
=
SVCCTL_STARTED_EVENT
;
HANDLE
htok
;
HANDLE
started_event
,
htok
;
DWORD
err
;
g_hStartedE
vent
=
CreateEventW
(
NULL
,
TRUE
,
FALSE
,
svcctl_started_event
);
started_e
vent
=
CreateEventW
(
NULL
,
TRUE
,
FALSE
,
svcctl_started_event
);
if
(
OpenProcessToken
(
GetCurrentProcess
(),
TOKEN_QUERY
|
TOKEN_DUPLICATE
,
&
htok
))
{
...
...
@@ -1019,8 +1018,10 @@ int main(int argc, char *argv[])
if
((
err
=
RPC_Init
())
==
ERROR_SUCCESS
)
{
scmdatabase_autostart_services
(
active_database
);
events_loop
();
SetEvent
(
started_event
);
WaitForSingleObject
(
exit_event
,
INFINITE
);
scmdatabase_wait_terminate
(
active_database
);
RPC_Stop
();
}
scmdatabase_destroy
(
active_database
);
if
(
env
)
...
...
programs/services/services.h
View file @
9dfa1022
...
...
@@ -98,13 +98,12 @@ void release_process(struct process_entry *process);
BOOL
process_send_command
(
struct
process_entry
*
process
,
const
void
*
data
,
DWORD
size
,
DWORD
*
result
);
void
process_terminate
(
struct
process_entry
*
process
);
extern
HANDLE
g_hStartedEvent
;
extern
DWORD
service_pipe_timeout
;
extern
DWORD
service_kill_timeout
;
extern
HANDLE
exit_event
;
DWORD
RPC_Init
(
void
);
DWORD
events_lo
op
(
void
);
void
RPC_St
op
(
void
);
/* from utils.c */
LPWSTR
strdupW
(
LPCWSTR
str
);
...
...
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