| 2717 | } |
| 2718 | |
| 2719 | static bool runtime_client_exchange(cbm_daemon_runtime_client_t *client, |
| 2720 | cbm_daemon_runtime_operation_t operation, const void *request, |
| 2721 | uint32_t request_length, uint32_t timeout_ms, |
| 2722 | uint8_t **response_out, uint32_t expected_response_length) { |
| 2723 | *response_out = NULL; |
| 2724 | if (timeout_ms == CBM_DAEMON_IPC_WAIT_FOREVER) { |
| 2725 | return false; |
| 2726 | } |
| 2727 | cbm_mutex_lock(&client->exchange_mutex); |
| 2728 | cbm_mutex_lock(&client->state_mutex); |
| 2729 | if (!client->usable || client->closing || !client->connection) { |
| 2730 | cbm_mutex_unlock(&client->state_mutex); |
| 2731 | cbm_mutex_unlock(&client->exchange_mutex); |
| 2732 | return false; |
| 2733 | } |
| 2734 | cbm_daemon_ipc_connection_t *connection = client->connection; |
| 2735 | client->exchange_active = true; |
| 2736 | cbm_mutex_unlock(&client->state_mutex); |
| 2737 | |
| 2738 | cbm_mutex_lock(&client->send_mutex); |
| 2739 | bool sent = cbm_daemon_ipc_send_frame(connection, CBM_DAEMON_FRAME_REQUEST, (uint16_t)operation, |
| 2740 | request, request_length); |
| 2741 | cbm_mutex_unlock(&client->send_mutex); |
| 2742 | cbm_daemon_frame_t frame = {0}; |
| 2743 | uint8_t *payload = NULL; |
| 2744 | int received = |
| 2745 | sent ? cbm_daemon_ipc_receive_frame(connection, timeout_ms, &frame, &payload) : -1; |
| 2746 | bool valid = sent && received == 1 && frame.type == CBM_DAEMON_FRAME_RESPONSE && |
| 2747 | frame.flags == (uint16_t)operation && frame.length == expected_response_length; |
| 2748 | cbm_mutex_lock(&client->state_mutex); |
| 2749 | client->exchange_active = false; |
| 2750 | if (!valid) { |
| 2751 | client->usable = false; |
| 2752 | } |
| 2753 | cbm_mutex_unlock(&client->state_mutex); |
| 2754 | if (!valid) { |
| 2755 | free(payload); |
| 2756 | } else { |
| 2757 | *response_out = payload; |
| 2758 | } |
| 2759 | cbm_mutex_unlock(&client->exchange_mutex); |
| 2760 | return valid; |
| 2761 | } |
| 2762 | |
| 2763 | cbm_daemon_subscription_result_t cbm_daemon_runtime_client_job_subscribe( |
| 2764 | cbm_daemon_runtime_client_t *client, const char *project_key, |
no test coverage detected