| 465 | } |
| 466 | |
| 467 | size_t cbm_daemon_expire_leases(cbm_daemon_coordinator_t *coordinator, uint64_t now_ms) { |
| 468 | if (!coordinator) { |
| 469 | return 0; |
| 470 | } |
| 471 | |
| 472 | size_t expired_count = 0; |
| 473 | cbm_daemon_callback_batch_t batch; |
| 474 | cbm_mutex_lock(&coordinator->mutex); |
| 475 | callback_batch_init_locked(coordinator, &batch); |
| 476 | cbm_daemon_client_t **cursor = &coordinator->clients; |
| 477 | while (*cursor) { |
| 478 | cbm_daemon_client_t *client = *cursor; |
| 479 | bool expired = now_ms >= client->last_heartbeat_ms && |
| 480 | now_ms - client->last_heartbeat_ms >= coordinator->lease_timeout_ms; |
| 481 | if (!expired) { |
| 482 | cursor = &client->next; |
| 483 | continue; |
| 484 | } |
| 485 | *cursor = client->next; |
| 486 | release_client_locked(coordinator, client, &batch); |
| 487 | expired_count++; |
| 488 | } |
| 489 | cbm_mutex_unlock(&coordinator->mutex); |
| 490 | |
| 491 | callback_batch_run(coordinator, &batch); |
| 492 | return expired_count; |
| 493 | } |
| 494 | |
| 495 | size_t cbm_daemon_active_clients(cbm_daemon_coordinator_t *coordinator) { |
| 496 | if (!coordinator) { |
no test coverage detected