| 568 | } |
| 569 | |
| 570 | cbm_daemon_subscription_result_t cbm_daemon_watch_subscribe( |
| 571 | cbm_daemon_coordinator_t *coordinator, cbm_daemon_client_id_t client_id, |
| 572 | const char *project_key, cbm_daemon_subscription_id_t *subscription_id) { |
| 573 | if (subscription_id) { |
| 574 | *subscription_id = CBM_DAEMON_SUBSCRIPTION_ID_INVALID; |
| 575 | } |
| 576 | if (!coordinator || !subscription_id || !project_key || project_key[0] == '\0' || |
| 577 | client_id == CBM_DAEMON_CLIENT_ID_INVALID) { |
| 578 | return CBM_DAEMON_SUBSCRIPTION_REJECTED; |
| 579 | } |
| 580 | |
| 581 | cbm_mutex_lock(&coordinator->mutex); |
| 582 | if (coordinator->state != CBM_DAEMON_COORDINATOR_RUNNING || |
| 583 | !find_client_locked(coordinator, client_id)) { |
| 584 | cbm_mutex_unlock(&coordinator->mutex); |
| 585 | return CBM_DAEMON_SUBSCRIPTION_REJECTED; |
| 586 | } |
| 587 | cbm_daemon_watch_t *watch = find_watch_locked(coordinator, project_key); |
| 588 | bool started = watch == NULL; |
| 589 | cbm_daemon_watch_t *new_watch = NULL; |
| 590 | char *key_copy = NULL; |
| 591 | cbm_daemon_subscription_t *subscription = malloc(sizeof(*subscription)); |
| 592 | if (started) { |
| 593 | new_watch = calloc(1, sizeof(*new_watch)); |
| 594 | key_copy = daemon_string_dup(project_key); |
| 595 | } |
| 596 | if (!subscription || (started && (!new_watch || !key_copy))) { |
| 597 | free(subscription); |
| 598 | free(new_watch); |
| 599 | free(key_copy); |
| 600 | cbm_mutex_unlock(&coordinator->mutex); |
| 601 | return CBM_DAEMON_SUBSCRIPTION_REJECTED; |
| 602 | } |
| 603 | |
| 604 | cbm_daemon_subscription_id_t id = issue_subscription_id_locked(coordinator); |
| 605 | if (id == CBM_DAEMON_SUBSCRIPTION_ID_INVALID) { |
| 606 | free(subscription); |
| 607 | free(new_watch); |
| 608 | free(key_copy); |
| 609 | cbm_mutex_unlock(&coordinator->mutex); |
| 610 | return CBM_DAEMON_SUBSCRIPTION_REJECTED; |
| 611 | } |
| 612 | if (started) { |
| 613 | new_watch->project_key = key_copy; |
| 614 | new_watch->next = coordinator->watches; |
| 615 | coordinator->watches = new_watch; |
| 616 | coordinator->watch_count++; |
| 617 | watch = new_watch; |
| 618 | } |
| 619 | subscription->id = id; |
| 620 | subscription->client_id = client_id; |
| 621 | subscription->next = watch->subscriptions; |
| 622 | watch->subscriptions = subscription; |
| 623 | watch->subscription_count++; |
| 624 | *subscription_id = id; |
| 625 | cbm_mutex_unlock(&coordinator->mutex); |
| 626 | return started ? CBM_DAEMON_SUBSCRIPTION_STARTED : CBM_DAEMON_SUBSCRIPTION_JOINED; |
| 627 | } |
no test coverage detected