diff options
Diffstat (limited to 'src/nm-cloud-setup/nm-cloud-setup-utils.c')
| -rw-r--r-- | src/nm-cloud-setup/nm-cloud-setup-utils.c | 252 |
1 files changed, 0 insertions, 252 deletions
diff --git a/src/nm-cloud-setup/nm-cloud-setup-utils.c b/src/nm-cloud-setup/nm-cloud-setup-utils.c index fb4883b7..75739c7c 100644 --- a/src/nm-cloud-setup/nm-cloud-setup-utils.c +++ b/src/nm-cloud-setup/nm-cloud-setup-utils.c @@ -166,258 +166,6 @@ nmcs_wait_for_objects_iterate_until_done(GMainContext *context, int timeout_msec /*****************************************************************************/ -typedef struct { - GTask *task; - GSource *source_timeout; - GSource *source_next_poll; - GMainContext *context; - GCancellable *internal_cancellable; - NMCSUtilsPollProbeStartFcn probe_start_fcn; - NMCSUtilsPollProbeFinishFcn probe_finish_fcn; - gpointer probe_user_data; - gulong cancellable_id; - gint64 last_poll_start_ms; - int sleep_timeout_ms; - int ratelimit_timeout_ms; - bool completed : 1; -} PollTaskData; - -static void -_poll_task_data_free(gpointer data) -{ - PollTaskData *poll_task_data = data; - - nm_assert(G_IS_TASK(poll_task_data->task)); - nm_assert(!poll_task_data->source_next_poll); - nm_assert(!poll_task_data->source_timeout); - nm_assert(poll_task_data->cancellable_id == 0); - - g_main_context_unref(poll_task_data->context); - - nm_g_slice_free(poll_task_data); -} - -static void -_poll_return(PollTaskData *poll_task_data, GError *error_take) -{ - nm_clear_g_source_inst(&poll_task_data->source_next_poll); - nm_clear_g_source_inst(&poll_task_data->source_timeout); - nm_clear_g_cancellable_disconnect(g_task_get_cancellable(poll_task_data->task), - &poll_task_data->cancellable_id); - - nm_clear_g_cancellable(&poll_task_data->internal_cancellable); - - if (error_take) - g_task_return_error(poll_task_data->task, g_steal_pointer(&error_take)); - else - g_task_return_boolean(poll_task_data->task, TRUE); - - g_object_unref(poll_task_data->task); -} - -static gboolean _poll_start_cb(gpointer user_data); - -static void -_poll_done_cb(GObject *source, GAsyncResult *result, gpointer user_data) -{ - PollTaskData *poll_task_data = user_data; - _nm_unused gs_unref_object GTask *task = - poll_task_data->task; /* balance ref from _poll_start_cb() */ - gs_free_error GError *error = NULL; - gint64 now_ms; - gint64 wait_ms; - gboolean is_finished; - - is_finished = - poll_task_data->probe_finish_fcn(source, result, poll_task_data->probe_user_data, &error); - - if (nm_utils_error_is_cancelled(error)) { - /* we already handle this differently. Nothing to do. */ - return; - } - - if (error || is_finished) { - _poll_return(poll_task_data, g_steal_pointer(&error)); - return; - } - - now_ms = nm_utils_get_monotonic_timestamp_msec(); - if (poll_task_data->ratelimit_timeout_ms > 0) - wait_ms = - (poll_task_data->last_poll_start_ms + poll_task_data->ratelimit_timeout_ms) - now_ms; - else - wait_ms = 0; - if (poll_task_data->sleep_timeout_ms > 0) - wait_ms = MAX(wait_ms, poll_task_data->sleep_timeout_ms); - - poll_task_data->source_next_poll = - nm_g_source_attach(nm_g_timeout_source_new(MAX(1, wait_ms), - G_PRIORITY_DEFAULT, - _poll_start_cb, - poll_task_data, - NULL), - poll_task_data->context); -} - -static gboolean -_poll_start_cb(gpointer user_data) -{ - PollTaskData *poll_task_data = user_data; - - nm_clear_g_source_inst(&poll_task_data->source_next_poll); - - poll_task_data->last_poll_start_ms = nm_utils_get_monotonic_timestamp_msec(); - - g_object_ref(poll_task_data->task); /* balanced by _poll_done_cb() */ - - poll_task_data->probe_start_fcn(poll_task_data->internal_cancellable, - poll_task_data->probe_user_data, - _poll_done_cb, - poll_task_data); - - return G_SOURCE_CONTINUE; -} - -static gboolean -_poll_timeout_cb(gpointer user_data) -{ - PollTaskData *poll_task_data = user_data; - - _poll_return(poll_task_data, nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN, "timeout expired")); - return G_SOURCE_CONTINUE; -} - -static void -_poll_cancelled_cb(GObject *object, gpointer user_data) -{ - PollTaskData *poll_task_data = user_data; - GError *error = NULL; - - nm_clear_g_signal_handler(g_task_get_cancellable(poll_task_data->task), - &poll_task_data->cancellable_id); - nm_utils_error_set_cancelled(&error, FALSE, NULL); - _poll_return(poll_task_data, error); -} - -/** - * nmcs_utils_poll: - * @poll_timeout_ms: if >= 0, then this is the overall timeout for how long we poll. - * When this timeout expires, the request completes with failure (and error set). - * @ratelimit_timeout_ms: if > 0, we ratelimit the starts from one prope_start_fcn - * call to the next. - * @sleep_timeout_ms: if > 0, then we wait after a probe finished this timeout - * before the next. Together with @ratelimit_timeout_ms this determines how - * frequently we probe. - * @probe_start_fcn: used to start a (asynchronous) probe. A probe must be completed - * by calling the provided callback. While a probe is in progress, we will not - * start another. This function is already invoked the first time synchronously, - * during nmcs_utils_poll(). - * @probe_finish_fcn: will be called from the callback of @probe_start_fcn. If the - * function returns %TRUE (polling done) or an error, polling stops. Otherwise, - * another poll will be started. - * @probe_user_data: user_data for the probe functions. - * @cancellable: cancellable for polling. - * @callback: when polling completes. - * @user_data: for @callback. - * - * This uses the current g_main_context_get_thread_default() for scheduling - * actions. - */ -void -nmcs_utils_poll(int poll_timeout_ms, - int ratelimit_timeout_ms, - int sleep_timeout_ms, - NMCSUtilsPollProbeStartFcn probe_start_fcn, - NMCSUtilsPollProbeFinishFcn probe_finish_fcn, - gpointer probe_user_data, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - PollTaskData *poll_task_data; - - poll_task_data = g_slice_new(PollTaskData); - *poll_task_data = (PollTaskData){ - .task = nm_g_task_new(NULL, cancellable, nmcs_utils_poll, callback, user_data), - .probe_start_fcn = probe_start_fcn, - .probe_finish_fcn = probe_finish_fcn, - .probe_user_data = probe_user_data, - .completed = FALSE, - .context = g_main_context_ref_thread_default(), - .sleep_timeout_ms = sleep_timeout_ms, - .ratelimit_timeout_ms = ratelimit_timeout_ms, - .internal_cancellable = g_cancellable_new(), - }; - - nmcs_wait_for_objects_register(poll_task_data->task); - - g_task_set_task_data(poll_task_data->task, poll_task_data, _poll_task_data_free); - - if (poll_timeout_ms >= 0) { - poll_task_data->source_timeout = - nm_g_source_attach(nm_g_timeout_source_new(poll_timeout_ms, - G_PRIORITY_DEFAULT, - _poll_timeout_cb, - poll_task_data, - NULL), - poll_task_data->context); - } - - poll_task_data->source_next_poll = nm_g_source_attach( - nm_g_idle_source_new(G_PRIORITY_DEFAULT_IDLE, _poll_start_cb, poll_task_data, NULL), - poll_task_data->context); - - if (cancellable) { - gulong signal_id; - - signal_id = g_cancellable_connect(cancellable, - G_CALLBACK(_poll_cancelled_cb), - poll_task_data, - NULL); - if (signal_id == 0) { - /* the request is already cancelled. Return. */ - return; - } - poll_task_data->cancellable_id = signal_id; - } -} - -/** - * nmcs_utils_poll_finish: - * @result: the GAsyncResult from the GAsyncReadyCallback callback. - * @probe_user_data: the user data provided to nmcs_utils_poll(). - * @error: the failure code. - * - * Returns: %TRUE if the polling completed with success. In that case, - * the error won't be set. - * If the request was cancelled, this is indicated by @error and - * %FALSE will be returned. - * If the probe returned a failure, this returns %FALSE and the error - * provided by @probe_finish_fcn. - * If the request times out, this returns %FALSE with error set. - * Error is always set if (and only if) the function returns %FALSE. - */ -gboolean -nmcs_utils_poll_finish(GAsyncResult *result, gpointer *probe_user_data, GError **error) -{ - GTask *task; - PollTaskData *poll_task_data; - - g_return_val_if_fail(nm_g_task_is_valid(result, NULL, nmcs_utils_poll), FALSE); - g_return_val_if_fail(!error || !*error, FALSE); - - task = G_TASK(result); - - if (probe_user_data) { - poll_task_data = g_task_get_task_data(task); - NM_SET_OUT(probe_user_data, poll_task_data->probe_user_data); - } - - return g_task_propagate_boolean(task, error); -} - -/*****************************************************************************/ - char * nmcs_utils_hwaddr_normalize(const char *hwaddr, gssize len) { |