Bachelor thesis - tevent
Michael Adam
obnox at samba.org
Wed Nov 28 04:14:53 MST 2012
On 2012-11-28 at 10:33 +0100, Volker Lendecke wrote:
> On Wed, Nov 28, 2012 at 10:26:13AM +0100, Jakub Hrozek wrote:
> > On Sun, Nov 25, 2012 at 09:19:19PM +0100, Volker Lendecke wrote:
> > > On Sun, Nov 25, 2012 at 06:23:11PM +0100, Koňař David wrote:
> > > > I'm working on a bachelor thesis about tevent event system under
> > > > supervision of Red Hat branch in Brno. One of its parts is to create
> > > > a tutorial for tevent.
> > > >
> > > > Right now I'm at the beginning of my work and I would like to ask
> > > > you if there are some important parts in tevent which I should pay
> > > > extra attention?
> > >
> > > Tevent as such is "just" another event library similar to
> > > libevent or libev or many others. It has two additional
> > > twists: It is based on talloc, and it can pass on the
> > > siginfo signal information. Beyond that's there is not
> > > really much that it adds.
> > >
> > > The piece that makes a difference is the tevent_req API.
> > > This enables composable async sequences of events to be
> > > coded in C relatively easy. See
> > > https://tevent.samba.org/group__tevent__request.html for a
> > > quick overview, and source3/winbind/*.c for a lot of
> > > examples how it is used.
> > >
> > > With best regards,
> > >
> > > Volker Lendecke
> >
> > I think I had an audio recording of your SambaXP talk on tevent a while
> > ago. It was only audio, though, no slides or video. Was there any more
> > recording of that talk? Maybe that would be helpful to David.
>
> Sorry, I do not have any slides, because I was showing code.
> At one time I went through developing a simple example
> online. We did not videotape that. I am happy to answer
> questions about tevent though.
>
> Someone might still have that example I developed in their
> samba-team folders. I have that archived somewhere, maybe
> someone else has quick access to that. Günther? Andreas
> maybe?
Attached find the git patchset to master from May.
I applied Volker's demo program, added it
also to the waf build and then worked some with the
demo code to learn/understand myself.
Cheers - Michael
-------------- next part --------------
From 81fdb2fb66eb0865b34d0454cb0b8f42c0c45baa Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Thu, 10 May 2012 12:01:25 +0200
Subject: [PATCH 1/3] SambaXP test code
---
source3/Makefile.in | 1 +
source3/torture/proto.h | 1 +
source3/torture/test_tevent_req.c | 151 +++++++++++++++++++++++++++++++++++++
source3/torture/torture.c | 1 +
4 files changed, 154 insertions(+)
create mode 100644 source3/torture/test_tevent_req.c
diff --git a/source3/Makefile.in b/source3/Makefile.in
index e289252..c429a75 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -1280,6 +1280,7 @@ SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/uta
torture/test_notify.o \
torture/test_dbwrap_watch.o \
torture/test_idmap_tdb_common.o \
+ torture/test_tevent_req.o \
torture/t_strappend.o
SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) $(TLDAP_OBJ) \
diff --git a/source3/torture/proto.h b/source3/torture/proto.h
index 80618ce..4232390 100644
--- a/source3/torture/proto.h
+++ b/source3/torture/proto.h
@@ -110,5 +110,6 @@ bool run_notify_bench2(int dummy);
bool run_notify_bench3(int dummy);
bool run_dbwrap_watch1(int dummy);
bool run_idmap_tdb_common_test(int dummy);
+bool run_test_tevent_req(int dummy);
#endif /* __TORTURE_H__ */
diff --git a/source3/torture/test_tevent_req.c b/source3/torture/test_tevent_req.c
new file mode 100644
index 0000000..c9049cd
--- /dev/null
+++ b/source3/torture/test_tevent_req.c
@@ -0,0 +1,151 @@
+/*
+ Unix SMB/CIFS implementation.
+ test tevent_req api
+ Copyright (C) Volker Lendecke 2012
+
+ This program 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 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "torture/proto.h"
+#include "lib/util/tevent_unix.h"
+#include "lib/util/tevent_ntstatus.h"
+
+struct hello_state {
+ struct tevent_context *ev;
+ const char *msg;
+ int interval;
+ int num_loops;
+};
+
+static void hello_waited(struct tevent_req *subreq);
+
+struct tevent_req *hello_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
+ const char *msg, int interval, int num_loops)
+{
+ struct tevent_req *req, *subreq;
+ struct hello_state *state;
+
+ req = tevent_req_create(mem_ctx, &state, struct hello_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->ev = ev;
+ state->msg = msg;
+ state->interval = interval;
+ state->num_loops = num_loops;
+
+ if (strlen(msg) == 0) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+
+ subreq = tevent_wakeup_send(
+ state, state->ev, timeval_current_ofs(state->interval, 0));
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, hello_waited, req);
+ return req;
+}
+
+static void hello_waited(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct hello_state *state = tevent_req_data(
+ req, struct hello_state);
+ bool ret;
+
+ ret = tevent_wakeup_recv(subreq);
+ TALLOC_FREE(subreq);
+ if (!ret) {
+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+ return;
+ }
+
+ printf("%s\n", state->msg);
+
+ state->num_loops -= 1;
+ if (state->num_loops == 0) {
+ tevent_req_done(req);
+ return;
+ }
+
+ subreq = tevent_wakeup_send(
+ state, state->ev, timeval_current_ofs(state->interval, 0));
+ if (tevent_req_nomem(subreq, req)) {
+ return;
+ }
+ tevent_req_set_callback(subreq, hello_waited, req);
+}
+
+NTSTATUS hello_recv(struct tevent_req *req)
+{
+ NTSTATUS status;
+
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+ return NT_STATUS_OK;
+}
+
+static void run_test_done(struct tevent_req *req)
+{
+ int *num_done = (int *)tevent_req_callback_data_void(req);
+ *num_done += 1;
+}
+
+bool run_test_tevent_req(int dummy)
+{
+ struct tevent_context *ev;
+ struct tevent_req *req;
+ int num_done;
+
+ printf("Running tevent_req test\n");
+
+ ev = tevent_context_init(talloc_tos());
+ if (ev == NULL) {
+ fprintf(stderr, "tevent_context_init failed\n");
+ return false;
+ }
+
+ num_done = 0;
+
+ req = hello_send(talloc_tos(), ev, "hello", 1, 5);
+ if (req == NULL) {
+ fprintf(stderr, "hello_send failed\n");
+ return false;
+ }
+ tevent_req_set_callback(req, run_test_done, &num_done);
+
+ req = hello_send(talloc_tos(), ev, "world", 2, 3);
+ if (req == NULL) {
+ fprintf(stderr, "hello_send failed\n");
+ return false;
+ }
+ tevent_req_set_callback(req, run_test_done, &num_done);
+
+ while (num_done < 2) {
+ int ret;
+
+ ret = tevent_loop_once(ev);
+ if (ret != 0) {
+ fprintf(stderr, "tevent_loop_once failed\n");
+ return false;
+ }
+ }
+
+ return true;
+}
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 83b0666..a00e638 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -9040,6 +9040,7 @@ static struct {
{ "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0},
{ "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0},
{ "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0},
+ { "LOCAL-TEVENT-REQ", run_test_tevent_req, 0},
{NULL, NULL, 0}};
--
1.7.9.5
From adb9032098c181057d88c2cdb1f2ae286c04be80 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Fri, 18 May 2012 15:03:39 +0200
Subject: [PATCH 2/3] s3:build: add test_tevent_req.c to the s3-torture build
---
source3/wscript_build | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/source3/wscript_build b/source3/wscript_build
index 0b96ccc..cb6c498 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -552,7 +552,8 @@ SMBTORTURE_SRC1 = '''torture/torture.c torture/nbio.c torture/scanner.c torture/
lib/tevent_barrier.c
torture/test_dbwrap_watch.c
torture/test_idmap_tdb_common.c
- torture/t_strappend.c'''
+ torture/t_strappend.c
+ torture/test_tevent_req.c'''
SMBTORTURE_SRC = '''${SMBTORTURE_SRC1}
torture/wbc_async.c'''
--
1.7.9.5
From f0493c0fce12a24a08b12fac26405d8112995bd8 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Fri, 18 May 2012 15:05:26 +0200
Subject: [PATCH 3/3] s3:torture:test_tevent_req: some updates
---
source3/torture/test_tevent_req.c | 96 +++++++++++++++++++++++++++++--------
1 file changed, 77 insertions(+), 19 deletions(-)
diff --git a/source3/torture/test_tevent_req.c b/source3/torture/test_tevent_req.c
index c9049cd..ff459d5 100644
--- a/source3/torture/test_tevent_req.c
+++ b/source3/torture/test_tevent_req.c
@@ -22,6 +22,11 @@
#include "lib/util/tevent_unix.h"
#include "lib/util/tevent_ntstatus.h"
+/*
+ * =====================================================
+ * start of implementation of the async function "hello"
+ */
+
struct hello_state {
struct tevent_context *ev;
const char *msg;
@@ -31,6 +36,7 @@ struct hello_state {
static void hello_waited(struct tevent_req *subreq);
+static
struct tevent_req *hello_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
const char *msg, int interval, int num_loops)
{
@@ -91,6 +97,7 @@ static void hello_waited(struct tevent_req *subreq)
tevent_req_set_callback(subreq, hello_waited, req);
}
+static
NTSTATUS hello_recv(struct tevent_req *req)
{
NTSTATUS status;
@@ -101,17 +108,39 @@ NTSTATUS hello_recv(struct tevent_req *req)
return NT_STATUS_OK;
}
-static void run_test_done(struct tevent_req *req)
-{
- int *num_done = (int *)tevent_req_callback_data_void(req);
- *num_done += 1;
-}
+/*
+ * up to here: implementation of the async function "hello"
+ * ========================================================
+ */
+
+
+/*
+ * ==================================================
+ * from here: code calling the async function "hello"
+ */
+
+
+struct hello_input {
+ const char *message;
+ int interval;
+ int num_loops;
+};
+
+static struct hello_input hello_input[] = {
+ { "hello1", 1, 5 },
+ { "hello2", 2, 3 },
+ { "hello3", 1, 4 },
+ { NULL, 0, 0},
+};
+
+static void run_test_tevent_req_done(struct tevent_req *subreq);
bool run_test_tevent_req(int dummy)
{
struct tevent_context *ev;
struct tevent_req *req;
- int num_done;
+ int num_done, num_instances;
+ int count;
printf("Running tevent_req test\n");
@@ -121,23 +150,35 @@ bool run_test_tevent_req(int dummy)
return false;
}
- num_done = 0;
-
- req = hello_send(talloc_tos(), ev, "hello", 1, 5);
- if (req == NULL) {
- fprintf(stderr, "hello_send failed\n");
- return false;
+ /*
+ * determine number of instances
+ */
+ for (count = 0; hello_input[count].message != NULL; count++) {
}
- tevent_req_set_callback(req, run_test_done, &num_done);
+ num_instances = count;
- req = hello_send(talloc_tos(), ev, "world", 2, 3);
- if (req == NULL) {
- fprintf(stderr, "hello_send failed\n");
- return false;
+ num_done = 0;
+
+ /*
+ * fire off the instances of hello
+ */
+ for (count = 0; count < num_instances; count++) {
+ req = hello_send(talloc_tos(), ev,
+ hello_input[count].message,
+ hello_input[count].interval,
+ hello_input[count].num_loops);
+ if (req == NULL) {
+ fprintf(stderr, "hello_send failed\n");
+ return false;
+ }
+ tevent_req_set_callback(req, run_test_tevent_req_done,
+ &num_done);
}
- tevent_req_set_callback(req, run_test_done, &num_done);
- while (num_done < 2) {
+ /*
+ * wait for instances of hello to finish
+ */
+ while (num_done < num_instances) {
int ret;
ret = tevent_loop_once(ev);
@@ -149,3 +190,20 @@ bool run_test_tevent_req(int dummy)
return true;
}
+
+/**
+ * callback to get the "result" of the async fct "hello".
+ */
+static void run_test_tevent_req_done(struct tevent_req *req)
+{
+ int *num_done = (int *)tevent_req_callback_data_void(req);
+ NTSTATUS status;
+
+ status = hello_recv(req);
+ TALLOC_FREE(req);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("run_test_done: hello_recv failed: %s\n", nt_errstr(status));
+ }
+
+ *num_done += 1;
+}
--
1.7.9.5
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 206 bytes
Desc: not available
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20121128/3cabb32a/attachment.pgp>
More information about the samba-technical
mailing list