Changeset 3951046 in mainline
- Timestamp:
- 2025-06-16T19:32:56Z (16 hours ago)
- Branches:
- master
- Parents:
- 5c55eb7
- Location:
- uspace/lib/c/generic
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async/ports.c
r5c55eb7 r3951046 1 1 /* 2 * Copyright (c) 2025 Jiri Svoboda 2 3 * Copyright (c) 2006 Ondrej Palkovsky 3 4 * All rights reserved. … … 59 60 iface_t iface; 60 61 61 /** Interface ports*/62 hash_table_t port_hash_table;63 64 /** Next available port ID*/65 port_id_t port_id_avail;62 /** Interface connection handler */ 63 async_port_handler_t handler; 64 65 /** Client data */ 66 void *data; 66 67 } interface_t; 67 68 … … 73 74 port_id_t id; 74 75 75 /** Port connection handler */ 76 async_port_handler_t handler; 77 78 /** Client data */ 79 void *data; 76 /** Port interfaces */ 77 hash_table_t interface_hash_table; 80 78 } port_t; 81 79 … … 98 96 static void *fallback_port_data = NULL; 99 97 100 /** Futex guarding the interface hash table. */ 101 static fibril_rmutex_t interface_mutex; 102 static hash_table_t interface_hash_table; 98 /** Futex guarding the port hash table. */ 99 static fibril_rmutex_t port_mutex; 100 static hash_table_t port_hash_table; 101 /** Next available port ID */ 102 static port_id_t port_id_avail = 0; 103 103 104 104 static size_t interface_key_hash(const void *key) … … 158 158 }; 159 159 160 static interface_t *async_new_interface(iface_t iface) 160 static interface_t *async_new_interface(port_t *port, iface_t iface, 161 async_port_handler_t handler, void *data) 161 162 { 162 163 interface_t *interface = … … 164 165 if (!interface) 165 166 return NULL; 166 167 bool ret = hash_table_create(&interface->port_hash_table, 0, 0,168 &port_hash_table_ops);169 if (!ret) {170 free(interface);171 return NULL;172 }173 174 167 interface->iface = iface; 175 interface->port_id_avail = 0; 176 177 hash_table_insert(&interface_hash_table, &interface->link); 168 interface->handler = handler; 169 interface->data = data; 170 171 hash_table_insert(&port->interface_hash_table, &interface->link); 178 172 179 173 return interface; 180 174 } 181 175 182 static port_t *async_new_port(interface_t *interface, 183 async_port_handler_t handler, void *data) 176 static port_t *async_new_port(void) 184 177 { 185 178 // TODO: Move the malloc out of critical section. … … 188 181 return NULL; 189 182 190 port_id_t id = interface->port_id_avail; 191 interface->port_id_avail++; 183 bool ret = hash_table_create(&port->interface_hash_table, 0, 0, 184 &interface_hash_table_ops); 185 if (!ret) { 186 free(port); 187 return NULL; 188 } 189 190 port_id_t id = port_id_avail; 191 port_id_avail++; 192 192 193 193 port->id = id; 194 port->handler = handler; 195 port->data = data; 196 197 hash_table_insert(&interface->port_hash_table, &port->link); 194 hash_table_insert(&port_hash_table, &port->link); 198 195 199 196 return port; … … 205 202 interface_t *interface; 206 203 207 fibril_rmutex_lock(&interface_mutex); 208 209 ht_link_t *link = hash_table_find(&interface_hash_table, &iface); 210 if (link) 211 interface = hash_table_get_inst(link, interface_t, link); 212 else 213 interface = async_new_interface(iface); 214 215 if (!interface) { 216 fibril_rmutex_unlock(&interface_mutex); 204 fibril_rmutex_lock(&port_mutex); 205 206 port_t *port = async_new_port(); 207 if (port == NULL) { 208 fibril_rmutex_unlock(&port_mutex); 217 209 return ENOMEM; 218 210 } 219 211 220 port_t *port = async_new_port(interface, handler, data); 221 if (!port) { 222 fibril_rmutex_unlock(&interface_mutex); 212 interface = async_new_interface(port, iface, handler, data); 213 if (interface == NULL) { 214 // XXX delete port 215 fibril_rmutex_unlock(&port_mutex); 223 216 return ENOMEM; 224 217 } 225 218 226 219 *port_id = port->id; 227 228 fibril_rmutex_unlock(&interface_mutex); 229 220 fibril_rmutex_unlock(&port_mutex); 230 221 return EOK; 231 222 } … … 248 239 } 249 240 250 static port_t *async_find_port(iface_t iface, port_id_t port_id) 251 { 252 port_t *port = NULL; 253 254 fibril_rmutex_lock(&interface_mutex); 255 256 ht_link_t *link = hash_table_find(&interface_hash_table, &iface); 257 if (link) { 258 interface_t *interface = 259 hash_table_get_inst(link, interface_t, link); 260 261 link = hash_table_find(&interface->port_hash_table, &port_id); 262 if (link) 263 port = hash_table_get_inst(link, port_t, link); 264 } 265 266 fibril_rmutex_unlock(&interface_mutex); 267 268 return port; 269 } 270 271 async_port_handler_t async_get_port_handler(iface_t iface, port_id_t port_id, 272 void **data) 241 typedef struct { 242 iface_t iface; 243 interface_t *interface; 244 } find_if_port_t; 245 246 static bool find_if_port(ht_link_t *link, void *arg) 247 { 248 find_if_port_t *fip = (find_if_port_t *)arg; 249 port_t *port; 250 interface_t *interface; 251 252 (void)arg; 253 port = hash_table_get_inst(link, port_t, link); 254 255 ht_link_t *ilink = hash_table_find(&port->interface_hash_table, 256 &fip->iface); 257 if (ilink) { 258 interface = hash_table_get_inst(ilink, interface_t, 259 link); 260 fip->interface = interface; 261 return false; 262 } 263 264 return true; 265 } 266 267 static interface_t *async_find_interface(iface_t iface, port_id_t port_id) 268 { 269 interface_t *interface = NULL; 270 find_if_port_t fip; 271 272 (void)port_id; // XXX !!! 273 274 fibril_rmutex_lock(&port_mutex); 275 276 /* 277 * XXX Find any port implementing that interface. In reality we should 278 * only look at port with ID port_id - but server.c does not 279 * provide us with a correct port ID 280 */ 281 282 fip.iface = iface; 283 fip.interface = NULL; 284 hash_table_apply(&port_hash_table, find_if_port, (void *)&fip); 285 interface = fip.interface; 286 287 fibril_rmutex_unlock(&port_mutex); 288 return interface; 289 } 290 291 async_port_handler_t async_get_interface_handler(iface_t iface, 292 port_id_t port_id, void **data) 273 293 { 274 294 assert(data); … … 277 297 *data = fallback_port_data; 278 298 279 port_t *port = async_find_port(iface, port_id);280 if ( port) {281 handler = port->handler;282 *data = port->data;299 interface_t *interface = async_find_interface(iface, port_id); 300 if (interface != NULL) { 301 handler = interface->handler; 302 *data = interface->data; 283 303 } 284 304 … … 286 306 } 287 307 288 /** Initialize the async framework .308 /** Initialize the async framework ports. 289 309 * 290 310 */ 291 311 void __async_ports_init(void) 292 312 { 293 if (fibril_rmutex_initialize(& interface_mutex) != EOK)313 if (fibril_rmutex_initialize(&port_mutex) != EOK) 294 314 abort(); 295 315 296 if (!hash_table_create(&interface_hash_table, 0, 0, 297 &interface_hash_table_ops)) 316 if (!hash_table_create(&port_hash_table, 0, 0, &port_hash_table_ops)) 298 317 abort(); 299 318 } … … 301 320 void __async_ports_fini(void) 302 321 { 303 fibril_rmutex_destroy(& interface_mutex);304 } 322 fibril_rmutex_destroy(&port_mutex); 323 } -
uspace/lib/c/generic/async/server.c
r5c55eb7 r3951046 1 1 /* 2 * Copyright (c) 2025 Jiri Svoboda 2 3 * Copyright (c) 2006 Ondrej Palkovsky 3 4 * All rights reserved. … … 955 956 void *data; 956 957 async_port_handler_t handler = 957 async_get_ port_handler(iface, 0, &data);958 async_get_interface_handler(iface, 0, &data); 958 959 959 960 async_new_connection(conn, call->task_id, call, handler, data); -
uspace/lib/c/generic/private/async.h
r5c55eb7 r3951046 1 1 /* 2 * Copyright (c) 2025 Jiri Svoboda 2 3 * Copyright (c) 2006 Ondrej Palkovsky 3 4 * All rights reserved. … … 103 104 extern errno_t async_create_port_internal(iface_t, async_port_handler_t, 104 105 void *, port_id_t *); 105 extern async_port_handler_t async_get_port_handler(iface_t, port_id_t, void **); 106 extern async_port_handler_t async_get_interface_handler(iface_t, port_id_t, 107 void **); 106 108 107 109 extern void async_reply_received(ipc_call_t *);
Note:
See TracChangeset
for help on using the changeset viewer.