| 423 | } |
| 424 | |
| 425 | bool cbm_daemon_client_disconnected(cbm_daemon_coordinator_t *coordinator, |
| 426 | cbm_daemon_client_id_t client_id, uint64_t now_ms) { |
| 427 | (void)now_ms; |
| 428 | if (!coordinator || client_id == CBM_DAEMON_CLIENT_ID_INVALID) { |
| 429 | return false; |
| 430 | } |
| 431 | |
| 432 | cbm_daemon_callback_batch_t batch; |
| 433 | cbm_mutex_lock(&coordinator->mutex); |
| 434 | callback_batch_init_locked(coordinator, &batch); |
| 435 | cbm_daemon_client_t **cursor = &coordinator->clients; |
| 436 | while (*cursor && (*cursor)->id != client_id) { |
| 437 | cursor = &(*cursor)->next; |
| 438 | } |
| 439 | if (!*cursor) { |
| 440 | cbm_mutex_unlock(&coordinator->mutex); |
| 441 | return false; |
| 442 | } |
| 443 | cbm_daemon_client_t *client = *cursor; |
| 444 | *cursor = client->next; |
| 445 | release_client_locked(coordinator, client, &batch); |
| 446 | cbm_mutex_unlock(&coordinator->mutex); |
| 447 | |
| 448 | callback_batch_run(coordinator, &batch); |
| 449 | return true; |
| 450 | } |
| 451 | |
| 452 | bool cbm_daemon_client_heartbeat(cbm_daemon_coordinator_t *coordinator, |
| 453 | cbm_daemon_client_id_t client_id, uint64_t now_ms) { |
no test coverage detected