Skip to content

Commit

Permalink
CMakeLists.txt: added requirement for gio-2.0 library
Browse files Browse the repository at this point in the history
handle.h: function signature for lr_handle_network_wait
handle.c: Added callback function required for GMainEventLoop

Adds API support for waiting on network in an event driven manner:
This waits for clients network interfaces till the specified time.
lr_handle_network_wait(priv->repo_handle, error, timeout_seconds)
This parses metalinkurl/baseurl and upon network-available signal,
it polls g_network_monitor_can_reach() with the help of
GMainEventLoop.
  • Loading branch information
RishabhSaini committed Sep 5, 2022
1 parent 66d4f81 commit ed12240
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 2 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
# Find necessare libraries

FIND_PACKAGE(PkgConfig)
PKG_CHECK_MODULES(GLIB2 glib-2.0>=2.28 REQUIRED)
PKG_CHECK_MODULES(GLIB2 glib-2.0>=2.28 gio-2.0 REQUIRED)
PKG_SEARCH_MODULE(LIBCRYPTO REQUIRED libcrypto openssl)
PKG_CHECK_MODULES(LIBXML2 libxml-2.0 REQUIRED)
FIND_PACKAGE(CURL 7.52.0 REQUIRED)
Expand Down
80 changes: 79 additions & 1 deletion librepo/handle.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <gio/gio.h>


#include "handle_internal.h"
Expand Down Expand Up @@ -264,6 +266,33 @@ lr_handle_remote_sources_changed(LrHandle *handle, LrChangedRemoteSource type)
}
}

struct callback_data {
GMainLoop *loop;
long input_seconds;
time_t begin;
GNetworkMonitor *monitor;
GSocketConnectable *connectable;
GCancellable *cancellable;
};

gboolean timeout_callback(gpointer data)
{
struct callback_data *dt = (struct callback_data*)data;
if(!g_network_monitor_can_reach(dt->monitor, dt->connectable, dt->cancellable, NULL) &&
time(NULL) - dt->begin <= dt->input_seconds){
return TRUE;
}
g_main_loop_quit(dt->loop);
return FALSE;
}

void on_network_available(GObject *object, GParamSpec *pspec, gpointer data)
{
g_timeout_add(200, timeout_callback, data);
struct callback_data *dt = (struct callback_data*)data;
g_main_loop_run(dt->loop);
}

gboolean
lr_handle_setopt(LrHandle *handle,
GError **err,
Expand Down Expand Up @@ -841,7 +870,56 @@ lr_handle_setopt(LrHandle *handle,
return ret;
}

static gboolean
gboolean
lr_handle_network_wait(LrHandle *handle, GError **err, guint seconds)
{

assert(!err || *err == NULL);

if (!handle) {
g_set_error(err, LR_HANDLE_ERROR, LRE_BADFUNCARG,
"No handle specified");
return FALSE;
}

GNetworkMonitor *monitor = g_network_monitor_get_default();
GCancellable *cancellable = g_cancellable_new ();

struct callback_data data_struct;
data_struct.input_seconds = seconds;
data_struct.begin = time(NULL);
data_struct.cancellable = cancellable;
data_struct.monitor = monitor;

gchar *baseurl;
if(handle->metalinkurl)
baseurl = handle->metalinkurl;
else if(handle->mirrorlisturl)
baseurl = handle->mirrorlisturl;
else if(handle->urls)
baseurl = handle->urls[0];
assert(baseurl);

GUri *uri = g_uri_parse(baseurl, G_URI_FLAGS_NONE, NULL);
if(uri == NULL){
return FALSE;
}
const gchar* scheme = g_uri_get_scheme(uri);
if(!g_strcmp0(scheme, "file")){
return TRUE;
}
const gchar* host = g_uri_get_host(uri);
guint16 port = g_uri_get_port(uri);
GSocketConnectable *connectable = g_network_address_new(host, port);
data_struct.connectable = connectable;
g_autoptr(GMainLoop) loop;
loop = g_main_loop_new(NULL, FALSE);
data_struct.loop = loop;
g_signal_connect(monitor, "notify::network-available", G_CALLBACK(on_network_available), &data_struct);
return TRUE;
}

gboolean
lr_handle_prepare_urls(LrHandle *handle, GError **err)
{
assert(!handle->urls_mirrors);
Expand Down
9 changes: 9 additions & 0 deletions librepo/handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,15 @@ lr_handle_getinfo(LrHandle *handle,
gboolean
lr_handle_perform(LrHandle *handle, LrResult *result, GError **err);

/** Handle waiting on network for LRO_URLS.
* @param handle Librepo handle.
* @param seconds Network timeout seconds
* @param err GError **
* @return TRUE if everything is ok, FALSE if err is set.
*/
gboolean
lr_handle_network_wait(LrHandle *handle, GError **err, guint seconds);

/** @} */

G_END_DECLS
Expand Down

0 comments on commit ed12240

Please sign in to comment.