1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00
samba-mirror/source3/utils/async-tracker.c
Ralph Boehme 4056bebf05 s3/async-tracker: don't ignore unknown options
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14828

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
2021-09-10 15:10:30 +00:00

316 lines
7.1 KiB
C

/*
* Copyright (C) 2011, Nokia <ivan.frade@nokia.com>
* Copyright (C) 2015, Noel Power <nopower@suse.com>
* Copyright (C) 2016, Ralph Boehme <slow@samba.org.>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "includes.h"
#include "lib/util/debug.h"
#include "lib/cmdline/cmdline.h"
#include "param.h"
/*
* glib uses TRUE and FALSE which was redefined by "includes.h" to be
* unusable, undefine so glib can establish its own working
* replacement.
*/
#undef TRUE
#undef FALSE
#include <glib.h>
#include <libtracker-sparql/tracker-sparql.h>
#include "lib/tevent_glib_glue.h"
enum loop_type {TEVENT_LOOP, GLIB_LOOP};
struct test_state {
enum loop_type loop_type;
TrackerSparqlConnection *connection;
GCancellable *cancellable;
GTimer *timer;
GMainLoop *loop;
struct tevent_context *ev;
struct tevent_glib_glue *glue;
};
static void cleanup(struct test_state *state)
{
g_cancellable_cancel(state->cancellable);
g_object_unref(state->cancellable);
g_timer_destroy(state->timer);
if (state->connection != NULL) {
g_object_unref(state->connection);
state->connection = NULL;
}
if (state->loop_type == GLIB_LOOP) {
g_main_loop_quit(state->loop);
} else {
samba_tevent_glib_glue_quit(state->glue);
}
}
static void cursor_cb(GObject *object,
GAsyncResult *res,
gpointer user_data)
{
struct test_state *state = talloc_get_type_abort(
user_data, struct test_state);
TrackerSparqlCursor *cursor = NULL;
GError *error = NULL;
gboolean more_results;
static gint i = 0;
cursor = TRACKER_SPARQL_CURSOR(object);
more_results = tracker_sparql_cursor_next_finish(cursor,
res,
&error);
if (error) {
g_critical("Could not run cursor next: %s", error->message);
if (cursor != NULL) {
g_object_unref(cursor);
}
g_error_free(error);
cleanup(state);
return;
}
if (!more_results) {
g_print("\n");
g_print("\nAsync cursor next took: %.6f (for all %d results)\n",
g_timer_elapsed (state->timer, NULL), i);
g_object_unref(cursor);
cleanup(state);
return;
}
if (i++ < 5) {
int num_cols = tracker_sparql_cursor_get_n_columns(cursor);
int col;
if (i == 1) {
g_print("Printing first 5 results:\n");
}
for (col = 0; col < num_cols; col++) {
g_print(" %s ", tracker_sparql_cursor_get_string(
cursor, col, NULL));
if (col == num_cols -1 ) {
g_print("\n");
}
}
if (i == 5) {
g_print(" ...\n");
g_print(" Printing nothing for remaining results\n");
}
}
tracker_sparql_cursor_next_async(cursor,
state->cancellable,
cursor_cb,
state);
}
static void query_cb(GObject *object,
GAsyncResult *res,
gpointer user_data)
{
struct test_state *state = talloc_get_type_abort(
user_data, struct test_state);
TrackerSparqlCursor *cursor = NULL;
GError *error = NULL;
g_print("Async query took: %.6f\n", g_timer_elapsed(state->timer, NULL));
cursor = tracker_sparql_connection_query_finish(
TRACKER_SPARQL_CONNECTION(object),
res,
&error);
if (error) {
g_critical("Could not run query: %s", error->message);
if (cursor) {
g_object_unref(cursor);
}
g_error_free(error);
cleanup(state);
return;
}
g_timer_start(state->timer);
tracker_sparql_cursor_next_async(cursor,
state->cancellable,
cursor_cb,
state);
}
static void connection_cb(GObject *object,
GAsyncResult *res,
gpointer user_data)
{
struct test_state *state = talloc_get_type_abort(
user_data, struct test_state);
GError *error = NULL;
g_print("Async connection took: %.6f\n",
g_timer_elapsed(state->timer, NULL));
state->connection = tracker_sparql_connection_get_finish(res, &error);
if (error) {
g_critical("Could not connect: %s", error->message);
g_error_free(error);
cleanup(state);
return;
}
g_timer_start(state->timer);
tracker_sparql_connection_query_async(
state->connection,
"SELECT ?name nie:mimeType(?s) nfo:fileName(?s) "
"WHERE { {?s nie:url ?name}}",
state->cancellable,
query_cb,
state);
}
static void debug_fn(void *private_data,
enum tevent_debug_level level,
const char *fmt,
va_list ap)
{
dbgtext_va(fmt, ap);
}
int main(int argc, const char **argv)
{
TALLOC_CTX *mem_ctx = NULL;
struct test_state *state = NULL;
int c;
poptContext pc;
bool ok;
struct poptOption long_options[] = {
POPT_AUTOHELP
{
.longName = "tevent",
.shortName = 't',
.argInfo = POPT_ARG_NONE,
.val = 'v',
.descrip = "Use tevent loop",
},
{
.longName = "glib",
.shortName = 'g',
.argInfo = POPT_ARG_NONE,
.val = 'g',
.descrip = "Use glib loop",
},
POPT_COMMON_SAMBA
POPT_COMMON_VERSION
POPT_TABLEEND
};
mem_ctx = talloc_new(NULL);
if (mem_ctx == NULL) {
exit(1);
}
state = talloc_zero(mem_ctx, struct test_state);
if (state == NULL) {
exit(1);
}
state->loop_type = TEVENT_LOOP;
smb_init_locale();
ok = samba_cmdline_init(mem_ctx,
SAMBA_CMDLINE_CONFIG_CLIENT,
true /* require_smbconf */);
if (!ok) {
TALLOC_FREE(mem_ctx);
exit(1);
}
pc = samba_popt_get_context(getprogname(),
argc,
argv,
long_options,
POPT_CONTEXT_KEEP_FIRST);
if (pc == NULL) {
TALLOC_FREE(mem_ctx);
exit(1);
}
while ((c = poptGetNextOpt(pc)) != -1) {
switch (c) {
case 'g':
state->loop_type = GLIB_LOOP;
break;
case 't':
state->loop_type = TEVENT_LOOP;
break;
case POPT_ERROR_BADOPT:
fprintf(stderr, "\nInvalid option %s: %s\n\n",
poptBadOption(pc, 0), poptStrerror(c));
poptPrintUsage(pc, stderr, 0);
exit(1);
}
}
if (state->loop_type == GLIB_LOOP) {
state->loop = g_main_loop_new(NULL, false);
} else {
state->ev = tevent_context_init(mem_ctx);
if (CHECK_DEBUGLVL(10)) {
tevent_set_debug(state->ev, debug_fn, NULL);
}
state->glue = samba_tevent_glib_glue_create(
mem_ctx, state->ev, g_main_context_default());
if (state->glue == NULL) {
printf("tevent_glib_glue_create failed\n");
exit(1);
}
}
state->timer = g_timer_new();
state->cancellable = g_cancellable_new();
tracker_sparql_connection_get_async(state->cancellable,
connection_cb,
state);
if (state->loop_type == GLIB_LOOP) {
printf("entering g_main_loop_run\n");
g_main_loop_run(state->loop);
} else {
printf("entering tevent_loop_wait\n");
tevent_loop_wait(state->ev);
TALLOC_FREE(state->glue);
TALLOC_FREE(state->ev);
}
TALLOC_FREE(mem_ctx);
poptFreeContext(pc);
return 0;
}