]> git.ipfire.org Git - pakfire.git/commitdiff
httpclient: Automatically launch when the event loop is started
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 27 Jun 2025 07:08:45 +0000 (07:08 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 27 Jun 2025 07:08:45 +0000 (07:08 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/httpclient.c

index bea8b077ba348f641431e834f67bcb62e0b509d6..1d4524fd3d1fa9a2cb44a43e31e94e84287298b6 100644 (file)
@@ -65,6 +65,12 @@ struct pakfire_httpclient {
        sd_event* loop;
        int still_running;
 
+       // Events
+       struct pakfire_httpclient_events {
+               sd_event_source* loop_started;
+               sd_event_source* loop_exited;
+       } events;
+
        // Timer
        sd_event_source* timer;
 
@@ -476,6 +482,61 @@ ERROR:
        return r;
 }
 
+static int pakfire_httpclient_loop_exited(sd_event_source* event, void* data);
+
+static int pakfire_httpclient_loop_started(sd_event_source* event, void* data) {
+       struct pakfire_httpclient* self = data;
+       int r;
+
+       // Start the progress
+       r = pakfire_progress_start(self->progress, self->total_downloadsize);
+       if (r < 0) {
+               ERROR(self->ctx, "Failed to start the progress meter: %s\n", strerror(-r));
+               return r;
+       }
+
+       // Launch some transfers
+       r = pakfire_httpclient_launch(self);
+       if (r < 0) {
+               ERROR(self->ctx, "Failed to launch some transfers: %s\n", strerror(-r));
+               return r;
+       }
+
+       // Register an event for when the loop exits
+       if (self->events.loop_exited)
+               sd_event_source_unref(self->events.loop_exited);
+
+       return sd_event_add_exit(self->loop,
+                       &self->events.loop_exited, pakfire_httpclient_loop_exited, self);
+}
+
+static int pakfire_httpclient_loop_exited(sd_event_source* event, void* data) {
+       struct pakfire_httpclient* self = data;
+       int r;
+
+       // Finish the progress
+       r = pakfire_progress_finish(self->progress);
+       if (r < 0) {
+               ERROR(self->ctx, "Failed to finish the progress meter: %s\n", strerror(-r));
+               return r;
+       }
+
+       // Log if there have been any transfers left running
+       if (pakfire_httpclient_num_running_xfers(self))
+               ERROR(self->ctx, "HTTP client ended with running transfers\n");
+
+       // Log if there have been any transfers left in the queue
+       if (pakfire_httpclient_num_queued_xfers(self))
+               ERROR(self->ctx, "Not all queued items have been downloaded\n");
+
+       // Register an event for when the loop exits
+       if (self->events.loop_started)
+               sd_event_source_unref(self->events.loop_started);
+
+       return sd_event_add_defer(self->loop,
+                       &self->events.loop_started, pakfire_httpclient_loop_started, self);
+}
+
 static int pakfire_httpclient_setup_loop(struct pakfire_httpclient* self) {
        int r;
 
@@ -496,6 +557,12 @@ static int pakfire_httpclient_setup_loop(struct pakfire_httpclient* self) {
                return r;
        }
 
+       // Register an event that gets triggered when the loop has been started
+       r = sd_event_add_defer(self->loop, &self->events.loop_started,
+                       pakfire_httpclient_loop_started, self);
+       if (r < 0)
+               return r;
+
        return 0;
 }
 
@@ -607,6 +674,12 @@ static void pakfire_httpclient_free(struct pakfire_httpclient* self) {
                pakfire_httpclient_xfer_free(e);
        }
 
+       // Events
+       if (self->events.loop_started)
+               sd_event_source_unref(self->events.loop_started);
+       if (self->events.loop_exited)
+               sd_event_source_unref(self->events.loop_exited);
+
        if (self->progress)
                pakfire_progress_unref(self->progress);
        if (self->curl)
@@ -736,16 +809,6 @@ int pakfire_httpclient_run(struct pakfire_httpclient* self, const char* title) {
 
        // Set the title
        r = pakfire_progress_set_title(self->progress, "%s", title);
-       if (r)
-               goto ERROR;
-
-       // Start the progress
-       r = pakfire_progress_start(self->progress, self->total_downloadsize);
-       if (r)
-               goto ERROR;
-
-       // Launch some transfers
-       r = pakfire_httpclient_launch(self);
        if (r < 0)
                goto ERROR;
 
@@ -756,23 +819,7 @@ int pakfire_httpclient_run(struct pakfire_httpclient* self, const char* title) {
                goto ERROR;
        }
 
-       if (pakfire_httpclient_num_running_xfers(self)) {
-               ERROR(self->ctx, "HTTP client ended with running transfers\n");
-               r = -ECANCELED;
-               goto ERROR;
-       }
-
-       if (pakfire_httpclient_num_queued_xfers(self)) {
-               ERROR(self->ctx, "Not all queued items have been downloaded\n");
-               r = -ECANCELED;
-               goto ERROR;
-       }
-
 ERROR:
-       // We are finished!
-       pakfire_progress_finish(self->progress);
-
-       // Reset
        self->flags &= ~PAKFIRE_HTTPCLIENT_TERMINATE_ON_COMPLETION;
 
        return r;