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
522bc15b
Commit
522bc15b
authored
Oct 22, 2012
by
Piotr Caban
Committed by
Alexandre Julliard
Oct 22, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
services: Kill service thread after timeout so it can terminate cleanly.
parent
8ebf0a72
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
116 additions
and
8 deletions
+116
-8
rpc.c
programs/services/rpc.c
+113
-5
services.c
programs/services/services.c
+2
-2
services.h
programs/services/services.h
+1
-1
No files found.
programs/services/rpc.c
View file @
522bc15b
...
...
@@ -84,6 +84,53 @@ 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
=
{
0
,
0
,
&
timeout_queue_cs
,
{
&
timeout_queue_cs_debug
.
ProcessLocksList
,
&
timeout_queue_cs_debug
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": timeout_queue_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
;
FILETIME
time
;
void
(
*
func
)(
struct
service_entry
*
);
struct
service_entry
*
service_entry
;
};
static
void
run_after_timeout
(
void
(
*
func
)(
struct
service_entry
*
),
struct
service_entry
*
service
,
DWORD
timeout
)
{
struct
timeout_queue_elem
*
elem
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
struct
timeout_queue_elem
));
ULARGE_INTEGER
time
;
if
(
!
elem
)
{
func
(
service
);
return
;
}
service
->
ref_count
++
;
elem
->
func
=
func
;
elem
->
service_entry
=
service
;
GetSystemTimeAsFileTime
(
&
elem
->
time
);
time
.
LowPart
=
elem
->
time
.
dwLowDateTime
;
time
.
HighPart
=
elem
->
time
.
dwHighDateTime
;
time
.
QuadPart
+=
timeout
*
10000000
;
elem
->
time
.
dwLowDateTime
=
time
.
LowPart
;
elem
->
time
.
dwHighDateTime
=
time
.
HighPart
;
EnterCriticalSection
(
&
timeout_queue_cs
);
list_add_head
(
&
timeout_queue
,
&
elem
->
entry
);
LeaveCriticalSection
(
&
timeout_queue_cs
);
SetEvent
(
timeout_queue_event
);
}
static
void
free_service_strings
(
struct
service_entry
*
old
,
struct
service_entry
*
new
)
{
QUERY_SERVICE_CONFIGW
*
old_cfg
=
&
old
->
config
;
...
...
@@ -700,7 +747,7 @@ DWORD __cdecl svcctl_SetServiceStatus(
service_unlock
(
service
->
service_entry
);
if
(
lpServiceStatus
->
dwCurrentState
==
SERVICE_STOPPED
)
service_terminate
(
service
->
service_entry
);
run_after_timeout
(
service_terminate
,
service
->
service_entry
,
service_kill_timeout
);
else
if
(
service
->
service_entry
->
status_changed_event
)
SetEvent
(
service
->
service_entry
->
status_changed_event
);
...
...
@@ -1567,10 +1614,16 @@ DWORD RPC_Init(void)
return
ERROR_SUCCESS
;
}
DWORD
RPC_MainL
oop
(
void
)
DWORD
events_l
oop
(
void
)
{
struct
timeout_queue_elem
*
iter
,
*
iter_safe
;
DWORD
err
;
HANDLE
hExitEvent
=
__wine_make_process_system
();
HANDLE
wait_handles
[
2
];
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
);
...
...
@@ -1578,12 +1631,67 @@ DWORD RPC_MainLoop(void)
do
{
err
=
WaitFor
SingleObjectEx
(
hExitEvent
,
INFINITE
,
TRUE
);
err
=
WaitFor
MultipleObjects
(
2
,
wait_handles
,
FALSE
,
timeout
);
WINE_TRACE
(
"Wait returned %d
\n
"
,
err
);
if
(
err
==
WAIT_OBJECT_0
+
1
||
err
==
WAIT_TIMEOUT
)
{
FILETIME
cur_time
;
ULARGE_INTEGER
time
;
GetSystemTimeAsFileTime
(
&
cur_time
);
time
.
LowPart
=
cur_time
.
dwLowDateTime
;
time
.
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
)
{
LeaveCriticalSection
(
&
timeout_queue_cs
);
iter
->
func
(
iter
->
service_entry
);
EnterCriticalSection
(
&
timeout_queue_cs
);
release_service
(
iter
->
service_entry
);
list_remove
(
&
iter
->
entry
);
HeapFree
(
GetProcessHeap
(),
0
,
iter
);
}
else
{
ULARGE_INTEGER
time_diff
;
time_diff
.
LowPart
=
iter
->
time
.
dwLowDateTime
;
time_diff
.
HighPart
=
iter
->
time
.
dwHighDateTime
;
time_diff
.
QuadPart
=
(
time_diff
.
QuadPart
-
time
.
QuadPart
)
/
10000
;
if
(
time_diff
.
QuadPart
<
timeout
)
timeout
=
time_diff
.
QuadPart
;
}
}
LeaveCriticalSection
(
&
timeout_queue_cs
);
if
(
timeout
!=
INFINITE
)
timeout
+=
1000
;
}
}
while
(
err
!=
WAIT_OBJECT_0
);
WINE_TRACE
(
"Object signaled - wine shutdown
\n
"
);
CloseHandle
(
hExitEvent
);
EnterCriticalSection
(
&
timeout_queue_cs
);
LIST_FOR_EACH_ENTRY_SAFE
(
iter
,
iter_safe
,
&
timeout_queue
,
struct
timeout_queue_elem
,
entry
)
{
LeaveCriticalSection
(
&
timeout_queue_cs
);
iter
->
func
(
iter
->
service_entry
);
EnterCriticalSection
(
&
timeout_queue_cs
);
release_service
(
iter
->
service_entry
);
list_remove
(
&
iter
->
entry
);
HeapFree
(
GetProcessHeap
(),
0
,
iter
);
}
LeaveCriticalSection
(
&
timeout_queue_cs
);
CloseHandle
(
wait_handles
[
0
]);
CloseHandle
(
wait_handles
[
1
]);
return
ERROR_SUCCESS
;
}
...
...
programs/services/services.c
View file @
522bc15b
...
...
@@ -40,7 +40,7 @@ HANDLE g_hStartedEvent;
struct
scmdatabase
*
active_database
;
DWORD
service_pipe_timeout
=
10000
;
DWORD
service_kill_timeout
=
2
0000
;
DWORD
service_kill_timeout
=
6
0000
;
static
DWORD
default_preshutdown_timeout
=
180000
;
static
void
*
env
=
NULL
;
...
...
@@ -914,7 +914,7 @@ int main(int argc, char *argv[])
if
((
err
=
RPC_Init
())
==
ERROR_SUCCESS
)
{
scmdatabase_autostart_services
(
active_database
);
RPC_MainL
oop
();
events_l
oop
();
scmdatabase_wait_terminate
(
active_database
);
}
scmdatabase_destroy
(
active_database
);
...
...
programs/services/services.h
View file @
522bc15b
...
...
@@ -88,7 +88,7 @@ extern DWORD service_pipe_timeout;
extern
DWORD
service_kill_timeout
;
DWORD
RPC_Init
(
void
);
DWORD
RPC_MainL
oop
(
void
);
DWORD
events_l
oop
(
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