Skip to content

Instantly share code, notes, and snippets.

@pabigot
Last active January 8, 2020 14:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pabigot/6176d58fc60b6f3f870209368a6caae4 to your computer and use it in GitHub Desktop.
Save pabigot/6176d58fc60b6f3f870209368a6caae4 to your computer and use it in GitHub Desktop.
example of service request with reset attempt for zephyrproject-rtos/zephyr pr #21090
int err;
struct k_poll_signal sig;
struct onoff_client cli;
/* Blocking start using signal */
struct k_poll_event evts[] = {
K_POLL_EVENT_INITIALIZER(K_POLL_TYPE_SIGNAL,
K_POLL_MODE_NOTIFY_ONLY,
&sig),
};
while (true) {
/* Request the service. */
k_poll_signal_reset(&sig);
onoff_client_init_signal(&cli, &sig);
err = onoff_request(srv, cli);
if ((err < 0) && (err != -EIO)) {
/* All errors other than -EIO are unrecoverable (except -EAGAIN
* which is only theoretical and could warrant trying again),
* probably due to being in an unsupported context or some other
* error. */
break;
}
/* Wait for result unless service is in error state, in which case
* we proceed directly to attempting a reset. */
if (err != -EIO) {
unsigned int signaled;
int result;
err = k_poll(evts, ARRAY_SIZE(evts), K_FOREVER);
if (err != 0) { /* k_poll failed */
break;
}
k_poll_signal_check(&sig, &signaled, &err);
/* Assume no need to checked signaled */
if (err == -EWOULDBLOCK) {
/* Loop back and try again hoping this time the operation will
* be invoked from a supported context. */
continue;
}
if (err >= 0) {
/* Success, service is on. Note: Services may indicate success
* with a positive value. */
break;
}
/* Asynchronous operation failed. Service is probably in an error
* state, but may be recoverable. Continue into reset code. */
}
/* Service may be in an error state. Try to reset it. */
k_poll_signal_reset(&sig);
onoff__init_signal(&cli, &sig);
err = onoff_service_reset(srv, cli);
if ((err == 0) || (err == -EALREADY)) {
/* Service is not in error state. Try the request again. */
continue;
}
if (err < 0) {
/* Service cannot be reset */
break;
}
/* Wait for the reset result */
err = k_poll(evts, ARRAY_SIZE(evts), K_FOREVER);
if (err != 0) { /* k_poll failed */
break;
}
k_poll_signal_check(&sig, &signaled, &err);
/* Assume no need to checked signaled */
if (err < 0) {
/* Failure to reset cannot be recovered from here. */
break;
}
/* Reset succeeded, try again */
}
/* Check err: service is on if value is non-negative. */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment