managers.c revision 1.4.2.2 1 /* $NetBSD: managers.c,v 1.4.2.2 2024/02/29 12:35:01 martin Exp $ */
2
3 /*
4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 *
6 * SPDX-License-Identifier: MPL-2.0
7 *
8 * This Source Code Form is subject to the terms of the Mozilla Public
9 * License, v. 2.0. If a copy of the MPL was not distributed with this
10 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11 *
12 * See the COPYRIGHT file distributed with this work for additional
13 * information regarding copyright ownership.
14 */
15
16 #include <isc/managers.h>
17 #include <isc/util.h>
18
19 #include "netmgr_p.h"
20 #include "task_p.h"
21 #include "timer_p.h"
22
23 isc_result_t
24 isc_managers_create(isc_mem_t *mctx, size_t workers, size_t quantum,
25 isc_nm_t **netmgrp, isc_taskmgr_t **taskmgrp,
26 isc_timermgr_t **timermgrp) {
27 isc_result_t result;
28 isc_nm_t *netmgr = NULL;
29 isc_taskmgr_t *taskmgr = NULL;
30 isc_timermgr_t *timermgr = NULL;
31
32 REQUIRE(netmgrp != NULL && *netmgrp == NULL);
33 isc__netmgr_create(mctx, workers, &netmgr);
34 *netmgrp = netmgr;
35 INSIST(netmgr != NULL);
36
37 REQUIRE(taskmgrp == NULL || *taskmgrp == NULL);
38 if (taskmgrp != NULL) {
39 INSIST(netmgr != NULL);
40 result = isc__taskmgr_create(mctx, quantum, netmgr, &taskmgr);
41 if (result != ISC_R_SUCCESS) {
42 UNEXPECTED_ERROR("isc_taskmgr_create() failed: %s",
43 isc_result_totext(result));
44 goto fail;
45 }
46 *taskmgrp = taskmgr;
47 }
48
49 REQUIRE(timermgrp == NULL || *timermgrp == NULL);
50 if (timermgrp != NULL) {
51 result = isc__timermgr_create(mctx, &timermgr);
52 if (result != ISC_R_SUCCESS) {
53 UNEXPECTED_ERROR("isc_timermgr_create() failed: %s",
54 isc_result_totext(result));
55 goto fail;
56 }
57 *timermgrp = timermgr;
58 }
59
60 return (ISC_R_SUCCESS);
61 fail:
62 isc_managers_destroy(netmgrp, taskmgrp, timermgrp);
63
64 return (result);
65 }
66
67 void
68 isc_managers_destroy(isc_nm_t **netmgrp, isc_taskmgr_t **taskmgrp,
69 isc_timermgr_t **timermgrp) {
70 /*
71 * If we have a taskmgr to clean up, then we must also have a netmgr.
72 */
73 REQUIRE(taskmgrp == NULL || netmgrp != NULL);
74
75 /*
76 * The sequence of operations here is important:
77 *
78 * 1. Initiate shutdown of the taskmgr, sending shutdown events to
79 * all tasks that are not already shutting down.
80 */
81 if (taskmgrp != NULL) {
82 INSIST(*taskmgrp != NULL);
83 isc__taskmgr_shutdown(*taskmgrp);
84 }
85
86 /*
87 * 2. Initiate shutdown of the network manager, freeing clients
88 * and other resources and preventing new connections, but do
89 * not stop processing of existing events.
90 */
91 if (netmgrp != NULL) {
92 INSIST(*netmgrp != NULL);
93 isc__netmgr_shutdown(*netmgrp);
94 }
95
96 /*
97 * 3. Finish destruction of the task manager when all tasks
98 * have completed.
99 */
100 if (taskmgrp != NULL) {
101 isc__taskmgr_destroy(taskmgrp);
102 }
103
104 /*
105 * 4. Finish destruction of the netmgr, and wait until all
106 * references have been released.
107 */
108 if (netmgrp != NULL) {
109 isc__netmgr_destroy(netmgrp);
110 }
111
112 /*
113 * 5. Clean up the remaining managers.
114 */
115 if (timermgrp != NULL) {
116 INSIST(*timermgrp != NULL);
117 isc__timermgr_destroy(timermgrp);
118 }
119 }
120