2 * \brief Client handling internals for the process manager.
4 * Copyright (c) 2017, ETH Zurich.
7 * This file is distributed under the terms in the attached LICENSE file.
8 * If you do not find this file, copies can be found by writing to:
9 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
12 #include <collections/hash_table.h>
15 #include "pending_clients.h"
17 static collections_hash_table *spawn_table = NULL;
18 static collections_hash_table *spawn_with_caps_table = NULL;
19 static collections_hash_table *span_table = NULL;
20 static collections_hash_table *kill_table = NULL;
21 static collections_hash_table *exit_table = NULL;
22 static collections_hash_table *cleanup_table = NULL;
24 errval_t pending_clients_add(struct capref domain_cap,
25 struct proc_mgmt_binding *b, enum ClientType type,
28 collections_hash_table **table;
30 case ClientType_Spawn:
33 case ClientType_SpawnWithCaps:
34 table = &spawn_with_caps_table;
45 case ClientType_Cleanup:
46 table = &cleanup_table;
49 USER_PANIC("Unhandled client type %d\n", type);
53 collections_hash_create_with_buckets(table, HASH_INDEX_BUCKETS, NULL);
55 return PROC_MGMT_ERR_CREATE_CLIENTS_TABLE;
60 errval_t err = domain_cap_hash(domain_cap, &key);
61 if (err_is_fail(err)) {
65 struct pending_client *cl = (struct pending_client*) malloc(
66 sizeof(struct pending_client));
68 cl->domain_cap = domain_cap;
69 cl->core_id = core_id;
73 if (type == ClientType_Kill) {
74 // Special case: multiple clients might have issued a kill for some
75 // domain. Need to chain them together.
76 void *entry = collections_hash_find(*table, key);
78 struct pending_client* old = (struct pending_client*) entry;
79 collections_hash_delete(*table, key);
84 collections_hash_insert(*table, key, cl);
89 errval_t pending_clients_release(struct capref domain_cap, enum ClientType type,
90 struct pending_client **ret_cl)
93 errval_t err = domain_cap_hash(domain_cap, &key);
94 if (err_is_fail(err)) {
98 collections_hash_table *table;
100 case ClientType_Spawn:
103 case ClientType_SpawnWithCaps:
104 table = spawn_with_caps_table;
106 case ClientType_Span:
109 case ClientType_Kill:
112 case ClientType_Exit:
115 case ClientType_Cleanup:
116 table = cleanup_table;
119 USER_PANIC("Unhandled client type %d\n", type);
122 assert(table != NULL);
124 void *entry = collections_hash_find(table, key);
126 return PROC_MGMT_ERR_CLIENTS_TABLE_FIND;
128 struct pending_client *cl = (struct pending_client*) entry;
129 if (ret_cl != NULL) {
135 collections_hash_delete(table, key);
140 errval_t pending_clients_release_one(struct capref domain_cap,
141 enum ClientType type,
142 struct proc_mgmt_binding *b,
143 struct pending_client **ret_cl)
146 errval_t err = domain_cap_hash(domain_cap, &key);
147 if (err_is_fail(err)) {
151 collections_hash_table **table;
153 case ClientType_Spawn:
154 table = &spawn_table;
156 case ClientType_SpawnWithCaps:
157 table = &spawn_with_caps_table;
159 case ClientType_Span:
162 case ClientType_Kill:
165 case ClientType_Exit:
168 case ClientType_Cleanup:
169 table = &cleanup_table;
172 USER_PANIC("Unhandled client type %d\n", type);
175 void *entry = collections_hash_find(*table, key);
177 return PROC_MGMT_ERR_CLIENTS_TABLE_FIND;
179 struct pending_client *cl = (struct pending_client*) entry;
181 struct pending_client *tmp = cl;
183 if (ret_cl != NULL) {
189 while (cl->next != NULL) {
190 if (cl->next->b == b) {
191 struct pending_client *tmp = cl->next;
192 cl->next = cl->next->next;
193 if (ret_cl != NULL) {
204 collections_hash_delete(*table, key);
206 collections_hash_insert(*table, key, cl);