Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions app/src/studio/rpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,11 @@ static int send_response(const zmk_studio_Response *resp) {
pb_ostream_t stream = pb_ostream_for_tx_buf(user_data);

uint8_t framing_byte = FRAMING_SOF;
ring_buf_put(&rpc_tx_buf, &framing_byte, 1);
if (ring_buf_put(&rpc_tx_buf, &framing_byte, 1) != 1) {
LOG_ERR("RPC TX buffer full");
k_mutex_unlock(&rpc_transport_mutex);
return -ENOMEM;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Treating SOF put failure as error sounds fine? I've never hit error here yet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm on the fence here, whether there should be any attempt to retry a few times, and then return -ENOMEM if that fails? Would give the underlying transport a chance to empty the ring buffer to free space. I'd suggest we try that.

In the case of a failure, I usually prefer, when locking involved, to create a new local at the top of the function int ret = 0; and then in this branch, set ret = -ENOMEM; goto exit and update the exit: to return ret instead.


selected_transport->tx_notify(&rpc_tx_buf, 1, false, user_data);

Expand All @@ -199,11 +203,15 @@ static int send_response(const zmk_studio_Response *resp) {
#if !IS_ENABLED(CONFIG_NANOPB_NO_ERRMSG)
LOG_ERR("Failed to encode the message %s", stream.errmsg);
#endif // !IS_ENABLED(CONFIG_NANOPB_NO_ERRMSG)
k_mutex_unlock(&rpc_transport_mutex);
return -EINVAL;
}

framing_byte = FRAMING_EOF;
ring_buf_put(&rpc_tx_buf, &framing_byte, 1);
// If response is large, tx buffer can be full for async transport.
while (ring_buf_put(&rpc_tx_buf, &framing_byte, 1) == 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should ideally "give up" after a certain period/number of tries, and return, so we don't get stuck in an infinite loop, IMHO.

k_sleep(K_MSEC(1));
}

selected_transport->tx_notify(&rpc_tx_buf, 1, true, user_data);

Expand Down