2019-11-30 08:12:09 -06:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2019 Peter Bigot Consulting, LLC
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef ZEPHYR_INCLUDE_SYS_ONOFF_H_
|
|
|
|
#define ZEPHYR_INCLUDE_SYS_ONOFF_H_
|
|
|
|
|
|
|
|
#include <kernel.h>
|
|
|
|
#include <zephyr/types.h>
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @defgroup resource_mgmt_apis Resource Management APIs
|
|
|
|
* @ingroup kernel_apis
|
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Flag fields used to specify on-off service behavior.
|
|
|
|
*/
|
|
|
|
enum onoff_service_flags {
|
|
|
|
/**
|
|
|
|
* @brief Flag passed to onoff_service_init().
|
|
|
|
*
|
|
|
|
* When provided this indicates the start transition function
|
|
|
|
* may cause the calling thread to wait. This blocks attempts
|
|
|
|
* to initiate a transition from a non-thread context.
|
|
|
|
*/
|
|
|
|
ONOFF_SERVICE_START_SLEEPS = BIT(0),
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Flag passed to onoff_service_init().
|
|
|
|
*
|
|
|
|
* As with @ref ONOFF_SERVICE_START_SLEEPS but describing the
|
|
|
|
* stop transition function.
|
|
|
|
*/
|
|
|
|
ONOFF_SERVICE_STOP_SLEEPS = BIT(1),
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Flag passed to onoff_service_init().
|
|
|
|
*
|
|
|
|
* As with @ref ONOFF_SERVICE_START_SLEEPS but describing the
|
|
|
|
* reset transition function.
|
|
|
|
*/
|
|
|
|
ONOFF_SERVICE_RESET_SLEEPS = BIT(2),
|
|
|
|
|
|
|
|
/* Internal use. */
|
|
|
|
ONOFF_SERVICE_HAS_ERROR = BIT(3),
|
|
|
|
|
|
|
|
/* This and higher bits reserved for internal use. */
|
|
|
|
ONOFF_SERVICE_INTERNAL_BASE = BIT(4),
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Forward declaration */
|
|
|
|
struct onoff_service;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Signature used to notify an on-off service that a transition
|
|
|
|
* has completed.
|
|
|
|
*
|
|
|
|
* Functions of this type are passed to service-specific transition
|
|
|
|
* functions to be used to report the completion of the operation.
|
|
|
|
* The functions may be invoked from any context.
|
|
|
|
*
|
|
|
|
* @param srv the service for which transition was requested.
|
|
|
|
*
|
|
|
|
* @param res the result of the transition. This shall be
|
|
|
|
* non-negative on success, or a negative error code. If an error is
|
|
|
|
* indicated the service shall enter an error state.
|
|
|
|
*/
|
|
|
|
typedef void (*onoff_service_notify_fn)(struct onoff_service *srv,
|
|
|
|
int res);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Signature used by service implementations to effect a
|
|
|
|
* transition.
|
|
|
|
*
|
|
|
|
* Service definitions use two function pointers of this type to be
|
|
|
|
* notified that a transition is required, and a third optional one to
|
|
|
|
* reset service state.
|
|
|
|
*
|
|
|
|
* The start function will be called only from the off state.
|
|
|
|
*
|
|
|
|
* The stop function will be called only from the on state.
|
|
|
|
*
|
|
|
|
* The reset function may be called only when
|
|
|
|
* onoff_service_has_error() returns true.
|
|
|
|
*
|
|
|
|
* @param srv the service for which transition was requested.
|
|
|
|
*
|
|
|
|
* @param notify the function to be invoked when the transition has
|
|
|
|
* completed. The callee shall capture this parameter to notify on
|
|
|
|
* completion of asynchronous transitions. If the transition is not
|
|
|
|
* asynchronous, notify shall be invoked before the transition
|
|
|
|
* function returns.
|
|
|
|
*/
|
|
|
|
typedef void (*onoff_service_transition_fn)(struct onoff_service *srv,
|
|
|
|
onoff_service_notify_fn notify);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief State associated with an on-off service.
|
|
|
|
*
|
|
|
|
* No fields in this structure are intended for use by service
|
|
|
|
* providers or clients. The state is to be initialized once, using
|
|
|
|
* onoff_service_init(), when the service provider is initialized.
|
|
|
|
* In case of error it may be reset through the
|
|
|
|
* onoff_service_reset() API.
|
|
|
|
*/
|
|
|
|
struct onoff_service {
|
|
|
|
/* List of clients waiting for completion of reset or
|
|
|
|
* transition to on.
|
|
|
|
*/
|
|
|
|
sys_slist_t clients;
|
|
|
|
|
|
|
|
/* Function to invoke to transition the service to on. */
|
|
|
|
onoff_service_transition_fn start;
|
|
|
|
|
|
|
|
/* Function to invoke to transition the service to off. */
|
|
|
|
onoff_service_transition_fn stop;
|
|
|
|
|
|
|
|
/* Function to force the service state to reset, where
|
|
|
|
* supported.
|
|
|
|
*/
|
|
|
|
onoff_service_transition_fn reset;
|
|
|
|
|
|
|
|
/* Mutex protection for flags, clients, releaser, and refs. */
|
|
|
|
struct k_spinlock lock;
|
|
|
|
|
|
|
|
/* Client to be informed when transition to off completes. */
|
|
|
|
struct onoff_client *releaser;
|
|
|
|
|
|
|
|
/* Flags identifying the service state. */
|
|
|
|
u16_t flags;
|
|
|
|
|
|
|
|
/* Number of active clients for the service. */
|
|
|
|
u16_t refs;
|
|
|
|
};
|
|
|
|
|
|
|
|
/** @internal */
|
|
|
|
#define ONOFF_SERVICE_INITIALIZER(_start, _stop, _reset, _flags) { \
|
|
|
|
.start = _start, \
|
|
|
|
.stop = _stop, \
|
|
|
|
.reset = _reset, \
|
|
|
|
.flags = _flags, \
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Initialize an on-off service to off state.
|
|
|
|
*
|
|
|
|
* This function must be invoked exactly once per service instance, by
|
|
|
|
* the infrastructure that provides the service, and before any other
|
|
|
|
* on-off service API is invoked on the service.
|
|
|
|
*
|
|
|
|
* This function should never be invoked by clients of an on-off service.
|
|
|
|
*
|
|
|
|
* @param srv the service definition object to be initialized.
|
|
|
|
*
|
|
|
|
* @param start the function used to (initiate a) transition from off
|
|
|
|
* to on. This must not be null. Include @ref ONOFF_SERVICE_START_SLEEPS as
|
|
|
|
* appropriate in flags.
|
|
|
|
*
|
|
|
|
* @param stop the function used to (initiate a) transition from on to
|
|
|
|
* off. This must not be null. Include @ref ONOFF_SERVICE_STOP_SLEEPS
|
|
|
|
* as appropriate in flags.
|
|
|
|
*
|
|
|
|
* @param reset the function used to clear errors and force the
|
|
|
|
* service to an off state. Pass null if the service cannot or need
|
|
|
|
* not be reset. (Services where a transition operation can complete
|
|
|
|
* with an error notification should support the reset operation.)
|
|
|
|
* Include @ref ONOFF_SERVICE_RESET_SLEEPS as appropriate in flags.
|
|
|
|
*
|
|
|
|
* @param flags any or all of the flags mentioned above,
|
|
|
|
* e.g. @ref ONOFF_SERVICE_START_SLEEPS. Use of other flags produces an
|
|
|
|
* error.
|
|
|
|
*
|
|
|
|
* @retval 0 on success
|
|
|
|
* @retval -EINVAL if start, stop, or flags are invalid
|
|
|
|
*/
|
|
|
|
int onoff_service_init(struct onoff_service *srv,
|
|
|
|
onoff_service_transition_fn start,
|
|
|
|
onoff_service_transition_fn stop,
|
|
|
|
onoff_service_transition_fn reset,
|
|
|
|
u32_t flags);
|
|
|
|
|
|
|
|
/** @internal
|
|
|
|
*
|
|
|
|
* Flag fields used to specify on-off client behavior.
|
|
|
|
*
|
|
|
|
* These flags control whether calls to onoff_service_request() and
|
|
|
|
* onoff_service_release() are synchronous or asynchronous, and for
|
|
|
|
* asynchronous operations how the operation result is communicated to
|
|
|
|
* the client.
|
|
|
|
*/
|
|
|
|
enum onoff_client_flags {
|
|
|
|
/* Known-invalid field, used in validation */
|
|
|
|
ONOFF_CLIENT_NOTIFY_INVALID = 0,
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Indicates that no notification will be provided.
|
|
|
|
*
|
|
|
|
* Callers must check for completions using
|
|
|
|
* onoff_client_fetch_result().
|
|
|
|
*
|
|
|
|
* See onoff_client_init_spinwait().
|
|
|
|
*/
|
|
|
|
ONOFF_CLIENT_NOTIFY_SPINWAIT = 1,
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Select notification through @ref k_poll signal
|
|
|
|
*
|
|
|
|
* See onoff_client_init_signal().
|
|
|
|
*/
|
|
|
|
ONOFF_CLIENT_NOTIFY_SIGNAL = 2,
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Select notification through a user-provided callback.
|
|
|
|
*
|
|
|
|
* See onoff_client_init_callback().
|
|
|
|
*/
|
|
|
|
ONOFF_CLIENT_NOTIFY_CALLBACK = 3,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Forward declaration */
|
|
|
|
struct onoff_client;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Signature used to notify an on-off service client of the
|
|
|
|
* completion of an operation.
|
|
|
|
*
|
|
|
|
* These functions may be invoked from any context including
|
|
|
|
* pre-kernel, ISR, or cooperative or pre-emptible threads.
|
|
|
|
* Compatible functions must be isr-callable and non-suspendable.
|
|
|
|
*
|
|
|
|
* @param srv the service for which the operation was initiated.
|
|
|
|
*
|
|
|
|
* @param cli the client structure passed to the function that
|
|
|
|
* initiated the operation.
|
|
|
|
*
|
|
|
|
* @param user_data user data provided when the client structure was
|
|
|
|
* initialized with onoff_client_init_callback().
|
|
|
|
*
|
|
|
|
* @param res the result of the operation. Expected values are
|
|
|
|
* service-specific, but the value shall be non-negative if the
|
|
|
|
* operation succeeded, and negative if the operation failed.
|
|
|
|
*/
|
|
|
|
typedef void (*onoff_client_callback)(struct onoff_service *srv,
|
|
|
|
struct onoff_client *cli,
|
|
|
|
void *user_data,
|
|
|
|
int res);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief State associated with a client of an on-off service.
|
|
|
|
*
|
|
|
|
* Objects of this type are allocated by a client, which must use an
|
|
|
|
* initialization function (e.g. onoff_client_init_signal()) to
|
|
|
|
* configure them.
|
|
|
|
*
|
|
|
|
* Control of the object content transfers to the service provider
|
|
|
|
* when a pointer to the object is passed to any on-off service
|
|
|
|
* function. While the service provider controls the object the
|
|
|
|
* client must not change any object fields. Control reverts to the
|
|
|
|
* client:
|
|
|
|
* * if the call to the service API returns an error;
|
|
|
|
* * if the call to the service API succeeds for a no-wait operation;
|
|
|
|
* * when operation completion is posted (signalled or callback
|
|
|
|
* invoked).
|
|
|
|
*
|
2020-02-05 03:59:41 -06:00
|
|
|
* After control has reverted to the client the state object must be
|
|
|
|
* reinitialized for the next operation.
|
|
|
|
*
|
|
|
|
* The content of this structure is not public API: all configuration
|
|
|
|
* and inspection should be done with functions like
|
|
|
|
* onoff_client_init_callback() and onoff_client_fetch_result().
|
2019-11-30 08:12:09 -06:00
|
|
|
*/
|
|
|
|
struct onoff_client {
|
|
|
|
/* Links the client into the set of waiting service users. */
|
|
|
|
sys_snode_t node;
|
|
|
|
|
|
|
|
union async {
|
|
|
|
/* Pointer to signal used to notify client.
|
|
|
|
*
|
|
|
|
* The signal value corresponds to the res parameter
|
|
|
|
* of onoff_client_callback.
|
|
|
|
*/
|
|
|
|
struct k_poll_signal *signal;
|
|
|
|
|
|
|
|
/* Handler and argument for callback notification. */
|
|
|
|
struct callback {
|
|
|
|
onoff_client_callback handler;
|
|
|
|
void *user_data;
|
|
|
|
} callback;
|
|
|
|
} async;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The result of the operation.
|
|
|
|
*
|
|
|
|
* This is the value that was (or would be) passed to the
|
|
|
|
* async infrastructure. This field is the sole record of
|
|
|
|
* success or failure for no-wait synchronous operations.
|
|
|
|
*/
|
|
|
|
int volatile result;
|
|
|
|
|
|
|
|
/* Flags recording client state. */
|
|
|
|
u32_t volatile flags;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Check for and read the result of an asynchronous operation.
|
|
|
|
*
|
|
|
|
* @param op pointer to the object used to specify asynchronous
|
|
|
|
* function behavior and store completion information.
|
|
|
|
*
|
|
|
|
* @param result pointer to storage for the result of the operation.
|
|
|
|
* The result is stored only if the operation has completed.
|
|
|
|
*
|
|
|
|
* @retval 0 if the operation has completed.
|
|
|
|
* @retval -EAGAIN if the operation has not completed.
|
|
|
|
*/
|
|
|
|
static inline int onoff_client_fetch_result(const struct onoff_client *op,
|
|
|
|
int *result)
|
|
|
|
{
|
|
|
|
__ASSERT_NO_MSG(op != NULL);
|
|
|
|
__ASSERT_NO_MSG(result != NULL);
|
|
|
|
|
|
|
|
int rv = -EAGAIN;
|
|
|
|
|
|
|
|
if (op->flags == 0U) {
|
|
|
|
rv = 0;
|
|
|
|
*result = op->result;
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Initialize an on-off client to be used for a spin-wait
|
|
|
|
* operation notification.
|
|
|
|
*
|
|
|
|
* Clients that use this initialization receive no asynchronous
|
|
|
|
* notification, and instead must periodically check for completion
|
|
|
|
* using onoff_client_fetch_result().
|
|
|
|
*
|
2020-02-05 03:59:41 -06:00
|
|
|
* On completion of the operation the client object must be
|
|
|
|
* reinitialized before it can be re-used.
|
|
|
|
*
|
2019-11-30 08:12:09 -06:00
|
|
|
* @param cli pointer to the client state object.
|
|
|
|
*/
|
|
|
|
static inline void onoff_client_init_spinwait(struct onoff_client *cli)
|
|
|
|
{
|
|
|
|
__ASSERT_NO_MSG(cli != NULL);
|
|
|
|
|
|
|
|
*cli = (struct onoff_client){
|
|
|
|
.flags = ONOFF_CLIENT_NOTIFY_SPINWAIT,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Initialize an on-off client to be used for a signal
|
|
|
|
* operation notification.
|
|
|
|
*
|
|
|
|
* Clients that use this initialization will be notified of the
|
|
|
|
* completion of operations submitted through onoff_request() and
|
|
|
|
* onoff_release() through the provided signal.
|
|
|
|
*
|
2020-02-05 03:59:41 -06:00
|
|
|
* On completion of the operation the client object must be
|
|
|
|
* reinitialized before it can be re-used.
|
|
|
|
*
|
2019-11-30 08:12:09 -06:00
|
|
|
* @note
|
|
|
|
* @rst
|
|
|
|
* This capability is available only when :option:`CONFIG_POLL` is
|
|
|
|
* selected.
|
|
|
|
* @endrst
|
|
|
|
*
|
|
|
|
* @param cli pointer to the client state object.
|
|
|
|
*
|
|
|
|
* @param sigp pointer to the signal to use for notification. The
|
|
|
|
* value must not be null. The signal must be reset before the client
|
|
|
|
* object is passed to the on-off service API.
|
|
|
|
*/
|
|
|
|
static inline void onoff_client_init_signal(struct onoff_client *cli,
|
|
|
|
struct k_poll_signal *sigp)
|
|
|
|
{
|
|
|
|
__ASSERT_NO_MSG(cli != NULL);
|
|
|
|
__ASSERT_NO_MSG(sigp != NULL);
|
|
|
|
|
|
|
|
*cli = (struct onoff_client){
|
|
|
|
#ifdef CONFIG_POLL
|
|
|
|
.async = {
|
|
|
|
.signal = sigp,
|
|
|
|
},
|
|
|
|
#endif /* CONFIG_POLL */
|
|
|
|
.flags = ONOFF_CLIENT_NOTIFY_SIGNAL,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Initialize an on-off client to be used for a callback
|
|
|
|
* operation notification.
|
|
|
|
*
|
|
|
|
* Clients that use this initialization will be notified of the
|
|
|
|
* completion of operations submitted through on-off service API
|
|
|
|
* through the provided callback. Note that callbacks may be invoked
|
|
|
|
* from various contexts depending on the specific service; see
|
|
|
|
* @ref onoff_client_callback.
|
|
|
|
*
|
2020-02-05 03:59:41 -06:00
|
|
|
* On completion of the operation the client object must be
|
|
|
|
* reinitialized before it can be re-used.
|
|
|
|
*
|
2019-11-30 08:12:09 -06:00
|
|
|
* @param cli pointer to the client state object.
|
|
|
|
*
|
|
|
|
* @param handler a function pointer to use for notification.
|
|
|
|
*
|
|
|
|
* @param user_data an opaque pointer passed to the handler to provide
|
|
|
|
* additional context.
|
|
|
|
*/
|
|
|
|
static inline void onoff_client_init_callback(struct onoff_client *cli,
|
|
|
|
onoff_client_callback handler,
|
|
|
|
void *user_data)
|
|
|
|
{
|
|
|
|
__ASSERT_NO_MSG(cli != NULL);
|
|
|
|
__ASSERT_NO_MSG(handler != NULL);
|
|
|
|
|
|
|
|
*cli = (struct onoff_client){
|
|
|
|
.async = {
|
|
|
|
.callback = {
|
|
|
|
.handler = handler,
|
|
|
|
.user_data = user_data,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
.flags = ONOFF_CLIENT_NOTIFY_CALLBACK,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Request a reservation to use an on-off service.
|
|
|
|
*
|
|
|
|
* The return value indicates the success or failure of an attempt to
|
|
|
|
* initiate an operation to request the resource be made available.
|
|
|
|
* If initiation of the operation succeeds the result of the request
|
|
|
|
* operation is provided through the configured client notification
|
|
|
|
* method, possibly before this call returns.
|
|
|
|
*
|
|
|
|
* Note that the call to this function may succeed in a case where the
|
|
|
|
* actual request fails. Always check the operation completion
|
|
|
|
* result.
|
|
|
|
*
|
|
|
|
* As a specific example: A call to this function may succeed at a
|
|
|
|
* point while the service is still transitioning to off due to a
|
|
|
|
* previous call to onoff_release(). When the transition completes
|
|
|
|
* the service would normally start a transition to on. However, if
|
|
|
|
* the transition to off completed in a non-thread context, and the
|
|
|
|
* transition to on can sleep, the transition cannot be started and
|
|
|
|
* the request will fail with `-EWOULDBLOCK`.
|
|
|
|
*
|
|
|
|
* @param srv the service that will be used.
|
|
|
|
*
|
|
|
|
* @param cli a non-null pointer to client state providing
|
|
|
|
* instructions on synchronous expectations and how to notify the
|
|
|
|
* client when the request completes. Behavior is undefined if client
|
|
|
|
* passes a pointer object associated with an incomplete service
|
|
|
|
* operation.
|
|
|
|
*
|
|
|
|
* @retval Non-negative on successful (initiation of) request
|
|
|
|
* @retval -EIO if service has recorded an an error
|
|
|
|
* @retval -EINVAL if the parameters are invalid
|
|
|
|
* @retval -EAGAIN if the reference count would overflow
|
|
|
|
* @retval -EWOULDBLOCK if the function was invoked from non-thread
|
|
|
|
* context and successful initiation could result in an attempt to
|
|
|
|
* make the calling thread sleep.
|
|
|
|
*/
|
|
|
|
int onoff_request(struct onoff_service *srv,
|
|
|
|
struct onoff_client *cli);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Release a reserved use of an on-off service.
|
|
|
|
*
|
|
|
|
* The return value indicates the success or failure of an attempt to
|
|
|
|
* initiate an operation to release the resource. If initiation of
|
|
|
|
* the operation succeeds the result of the release operation itself
|
|
|
|
* is provided through the configured client notification method,
|
|
|
|
* possibly before this call returns.
|
|
|
|
*
|
|
|
|
* Note that the call to this function may succeed in a case where the
|
|
|
|
* actual release fails. Always check the operation completion
|
|
|
|
* result.
|
|
|
|
*
|
|
|
|
* @param srv the service that will be used.
|
|
|
|
*
|
|
|
|
* @param cli a non-null pointer to client state providing
|
|
|
|
* instructions on how to notify the client when release completes.
|
|
|
|
* Behavior is undefined if cli references an object associated with
|
|
|
|
* an incomplete service operation.
|
|
|
|
*
|
|
|
|
* @retval Non-negative on successful (initiation of) release
|
|
|
|
* @retval -EINVAL if the parameters are invalid
|
|
|
|
* @retval -EIO if service has recorded an an error
|
|
|
|
* @retval -EWOULDBLOCK if a non-blocking request was made and
|
|
|
|
* could not be satisfied without potentially blocking.
|
|
|
|
* @retval -EALREADY if the service is already off or transitioning
|
|
|
|
* to off
|
|
|
|
* @retval -EBUSY if the service is transitioning to on
|
|
|
|
*/
|
|
|
|
int onoff_release(struct onoff_service *srv,
|
|
|
|
struct onoff_client *cli);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Test whether an on-off service has recorded an error.
|
|
|
|
*
|
|
|
|
* This function can be used to determine whether the service has
|
|
|
|
* recorded an error. Errors may be cleared by invoking
|
|
|
|
* onoff_service_reset().
|
|
|
|
*
|
|
|
|
* @return true if and only if the service has an uncleared error.
|
|
|
|
*/
|
|
|
|
static inline bool onoff_service_has_error(const struct onoff_service *srv)
|
|
|
|
{
|
|
|
|
return (srv->flags & ONOFF_SERVICE_HAS_ERROR) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Clear errors on an on-off service and reset it to its off
|
|
|
|
* state.
|
|
|
|
*
|
|
|
|
* A service can only be reset when it is in an error state as
|
|
|
|
* indicated by onoff_service_has_error().
|
|
|
|
*
|
|
|
|
* The return value indicates the success or failure of an attempt to
|
|
|
|
* initiate an operation to reset the resource. If initiation of the
|
|
|
|
* operation succeeds the result of the reset operation itself is
|
|
|
|
* provided through the configured client notification method,
|
|
|
|
* possibly before this call returns. Multiple clients may request a
|
|
|
|
* reset; all are notified when it is complete.
|
|
|
|
*
|
|
|
|
* Note that the call to this function may succeed in a case where the
|
|
|
|
* actual reset fails. Always check the operation completion result.
|
|
|
|
*
|
|
|
|
* This function is blocking if the reset transition is blocking,
|
|
|
|
* unless client notification specifies no-wait.
|
|
|
|
*
|
|
|
|
* @note Due to the conditions on state transition all incomplete
|
|
|
|
* asynchronous operations will have been informed of the error when
|
|
|
|
* it occurred. There need be no concern about dangling requests left
|
|
|
|
* after a reset completes.
|
|
|
|
*
|
|
|
|
* @param srv the service to be reset.
|
|
|
|
*
|
|
|
|
* @param cli pointer to client state, including instructions on how
|
|
|
|
* to notify the client when reset completes. Behavior is undefined
|
|
|
|
* if cli references an object associated with an incomplete service
|
|
|
|
* operation.
|
|
|
|
*
|
|
|
|
* @retval 0 on success
|
|
|
|
* @retval -ENOTSUP if reset is not supported
|
|
|
|
* @retval -EINVAL if the parameters are invalid, or if the service
|
|
|
|
* @retval -EALREADY if the service does not have a recorded error
|
|
|
|
*/
|
|
|
|
int onoff_service_reset(struct onoff_service *srv,
|
|
|
|
struct onoff_client *cli);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Attempt to cancel an in-progress client operation.
|
|
|
|
*
|
|
|
|
* It may be that a client has initiated an operation but needs to
|
|
|
|
* shut down before the operation has completed. For example, when a
|
|
|
|
* request was made and the need is no longer present.
|
|
|
|
*
|
|
|
|
* There is limited support for cancelling an in-progress operation:
|
|
|
|
* * If a start or reset is in progress, all but one clients
|
|
|
|
* requesting the start can cancel their request.
|
|
|
|
* * If a stop is in progress, all clients requesting a restart can
|
|
|
|
* cancel their request;
|
|
|
|
* * A client requesting a release cannot cancel the release.
|
|
|
|
*
|
|
|
|
* Be aware that any transition that was initiated on behalf of the
|
|
|
|
* client will continue to progress to completion. The restricted
|
|
|
|
* support for cancellation ensures that for any in-progress
|
|
|
|
* transition there will always be at least one client that will be
|
|
|
|
* notified when the operation completes.
|
|
|
|
*
|
|
|
|
* If the cancellation fails the service retains control of the client
|
|
|
|
* object, and the client must wait for operation completion.
|
|
|
|
*
|
|
|
|
* @param srv the service for which an operation is to be cancelled.
|
|
|
|
*
|
|
|
|
* @param cli a pointer to the same client state that was provided
|
|
|
|
* when the operation to be cancelled was issued. If the cancellation
|
|
|
|
* is successful the client will be notified of operation completion
|
|
|
|
* with a result of `-ECANCELED`.
|
|
|
|
*
|
|
|
|
* @retval 0 if the cancellation was completed before the client could
|
|
|
|
* be notified. The client will be notified through cli with an
|
|
|
|
* operation completion of `-ECANCELED`.
|
|
|
|
* @retval -EINVAL if the parameters are invalid.
|
|
|
|
* @retval -EWOULDBLOCK if cancellation was rejected because the
|
|
|
|
* client is the only waiter for an in-progress transition. The
|
|
|
|
* service retains control of the client structure.
|
|
|
|
* @retval -EALREADY if cli was not a record of an uncompleted
|
|
|
|
* notification at the time the cancellation was processed. This
|
|
|
|
* likely indicates that the operation and client notification had
|
|
|
|
* already completed.
|
|
|
|
*/
|
|
|
|
int onoff_cancel(struct onoff_service *srv,
|
|
|
|
struct onoff_client *cli);
|
|
|
|
|
|
|
|
/** @} */
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* ZEPHYR_INCLUDE_SYS_ONOFF_H_ */
|