From 6617ff24f206335d595c585b96289542ead9cbe3 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Wed, 16 Mar 2016 04:31:31 +0100 Subject: [PATCH] services: Introduce refcounting for processes. Signed-off-by: Sebastian Lackner Signed-off-by: Alexandre Julliard --- programs/services/services.c | 9 ++++++++- programs/services/services.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/programs/services/services.c b/programs/services/services.c index 03df852078a..1119b25370d 100644 --- a/programs/services/services.c +++ b/programs/services/services.c @@ -73,6 +73,7 @@ static DWORD process_create(struct process_entry **entry) *entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**entry)); if (!*entry) return ERROR_NOT_ENOUGH_SERVER_MEMORY; + (*entry)->ref_count = 1; (*entry)->control_pipe = INVALID_HANDLE_VALUE; /* all other fields are zero */ return ERROR_SUCCESS; @@ -126,7 +127,7 @@ void free_service_entry(struct service_entry *entry) HeapFree(GetProcessHeap(), 0, entry->description); HeapFree(GetProcessHeap(), 0, entry->dependOnServices); HeapFree(GetProcessHeap(), 0, entry->dependOnGroups); - free_process_entry(entry->process); + release_process(entry->process); HeapFree(GetProcessHeap(), 0, entry); } @@ -455,6 +456,12 @@ struct service_entry *scmdatabase_find_service_by_displayname(struct scmdatabase return NULL; } +void release_process(struct process_entry *process) +{ + if (InterlockedDecrement(&process->ref_count) == 0) + free_process_entry(process); +} + void release_service(struct service_entry *service) { struct scmdatabase *db = service->db; diff --git a/programs/services/services.h b/programs/services/services.h index 206d655a902..b8f4774be2a 100644 --- a/programs/services/services.h +++ b/programs/services/services.h @@ -33,6 +33,7 @@ struct scmdatabase struct process_entry { + LONG ref_count; HANDLE process; HANDLE control_mutex; HANDLE control_pipe; @@ -87,6 +88,7 @@ void service_terminate(struct service_entry *service); /* Process functions */ +void release_process(struct process_entry *process); BOOL process_send_command(struct process_entry *process, const void *data, DWORD size, DWORD *result); extern HANDLE g_hStartedEvent;