| 503 | } |
| 504 | |
| 505 | cbm_daemon_subscription_result_t cbm_daemon_job_subscribe( |
| 506 | cbm_daemon_coordinator_t *coordinator, cbm_daemon_client_id_t client_id, |
| 507 | const char *project_key, cbm_daemon_subscription_id_t *subscription_id) { |
| 508 | if (subscription_id) { |
| 509 | *subscription_id = CBM_DAEMON_SUBSCRIPTION_ID_INVALID; |
| 510 | } |
| 511 | if (!coordinator || !subscription_id || !project_key || project_key[0] == '\0' || |
| 512 | client_id == CBM_DAEMON_CLIENT_ID_INVALID) { |
| 513 | return CBM_DAEMON_SUBSCRIPTION_REJECTED; |
| 514 | } |
| 515 | |
| 516 | cbm_mutex_lock(&coordinator->mutex); |
| 517 | if (coordinator->state != CBM_DAEMON_COORDINATOR_RUNNING || |
| 518 | !find_client_locked(coordinator, client_id)) { |
| 519 | cbm_mutex_unlock(&coordinator->mutex); |
| 520 | return CBM_DAEMON_SUBSCRIPTION_REJECTED; |
| 521 | } |
| 522 | cbm_daemon_job_t *job = find_job_locked(coordinator, project_key); |
| 523 | if (job && job->state != CBM_DAEMON_JOB_RUNNING) { |
| 524 | cbm_mutex_unlock(&coordinator->mutex); |
| 525 | return CBM_DAEMON_SUBSCRIPTION_REJECTED; |
| 526 | } |
| 527 | |
| 528 | bool started = job == NULL; |
| 529 | cbm_daemon_job_t *new_job = NULL; |
| 530 | char *key_copy = NULL; |
| 531 | cbm_daemon_subscription_t *subscription = malloc(sizeof(*subscription)); |
| 532 | if (started) { |
| 533 | new_job = calloc(1, sizeof(*new_job)); |
| 534 | key_copy = daemon_string_dup(project_key); |
| 535 | } |
| 536 | if (!subscription || (started && (!new_job || !key_copy))) { |
| 537 | free(subscription); |
| 538 | free(new_job); |
| 539 | free(key_copy); |
| 540 | cbm_mutex_unlock(&coordinator->mutex); |
| 541 | return CBM_DAEMON_SUBSCRIPTION_REJECTED; |
| 542 | } |
| 543 | |
| 544 | cbm_daemon_subscription_id_t id = issue_subscription_id_locked(coordinator); |
| 545 | if (id == CBM_DAEMON_SUBSCRIPTION_ID_INVALID) { |
| 546 | free(subscription); |
| 547 | free(new_job); |
| 548 | free(key_copy); |
| 549 | cbm_mutex_unlock(&coordinator->mutex); |
| 550 | return CBM_DAEMON_SUBSCRIPTION_REJECTED; |
| 551 | } |
| 552 | if (started) { |
| 553 | new_job->project_key = key_copy; |
| 554 | new_job->state = CBM_DAEMON_JOB_RUNNING; |
| 555 | new_job->next = coordinator->jobs; |
| 556 | coordinator->jobs = new_job; |
| 557 | coordinator->job_count++; |
| 558 | job = new_job; |
| 559 | } |
| 560 | subscription->id = id; |
| 561 | subscription->client_id = client_id; |
| 562 | subscription->next = job->subscriptions; |
no test coverage detected