[SCM] Samba Shared Repository - branch v3-6-test updated
Jeremy Allison
jra at samba.org
Thu Dec 30 11:21:15 MST 2010
The branch, v3-6-test has been updated
via 06e02df s3: Fix two uninitialized variables
via 61186b5 s3: Allow more control over smbsock_[any_]connect
via 5ea88af Use sockaddr_storage in async sendto/recvfrom (cherry picked from commit 65f4f22cb4a201fb3f4f4adbb576d3a8909d4bfd)
via 2a833a4 s3: Make name_query return NTSTATUS
via d7c32ae s3: AllowDebugChange is gone (cherry picked from commit 28d997a89056f144de6a7b95af0e54a044c5e5b3)
via 030f2ff Fix a crash in libnss_wins
via 073f002 s3: Make node_status_query return NTSTATUS
via ef6cb55 s3: Remove an ancient typedef (cherry picked from commit e1ab3c3470a7f1159d52ed0c1eacf4a5a7b6bc2b)
via 522cbb3 s3: Fix some typos (cherry picked from commit b0ff97d8d37957fc34861214b6cbab513072bef1)
via 80ef019 async_send->sendto, async_recv->recvfrom (cherry picked from commit c4b18bd860bc18529249a8c54c7db6aba2347591)
via 7371bf5 tdb:tdbtorture: use TEST_DATA_PREFIX for files
via 8b916ab tdb:tdbtest: use TEST_DATA_PREFIX for files
via 94d4655 testprogs: testspoolss.exe: pretty print FILETIME in driver info 6 and 8.
via 72b35f9 tevent: More documentation updates
from 489b1c1 s3:lib/netapi: don't set SAMR_FIELD_FULL_NAME if we just want to set the account name (bug #7896)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test
- Log -----------------------------------------------------------------
commit 06e02dfb9316ec96d711fa7455b4e947587a7f9a
Author: Volker Lendecke <vl at samba.org>
Date: Thu Dec 30 12:42:50 2010 +0100
s3: Fix two uninitialized variables
Autobuild-User: Volker Lendecke <vlendec at samba.org>
Autobuild-Date: Thu Dec 30 12:52:47 CET 2010 on sn-devel-104
(cherry picked from commit d05fb4b7b79fa5ef240864f0f0f544bbba1b59e3)
commit 61186b5281d23823a7ee99b7d552b2d8d7e07acc
Author: Volker Lendecke <vl at samba.org>
Date: Thu Dec 23 15:20:22 2010 +0100
s3: Allow more control over smbsock_[any_]connect
Autobuild-User: Volker Lendecke <vlendec at samba.org>
Autobuild-Date: Wed Dec 29 23:30:44 CET 2010 on sn-devel-104
(cherry picked from commit 86ff8cf227c759189080ade0deb4f5b184bb14f7)
commit 5ea88afaf4982d4f327897c6474034f9aae04d85
Author: Volker Lendecke <vl at samba.org>
Date: Wed Dec 29 08:46:08 2010 +0100
Use sockaddr_storage in async sendto/recvfrom
(cherry picked from commit 65f4f22cb4a201fb3f4f4adbb576d3a8909d4bfd)
commit 2a833a4621f3d7155dc7dfc5a7633dc68eba2dd0
Author: Volker Lendecke <vl at samba.org>
Date: Tue Dec 28 13:47:35 2010 +0100
s3: Make name_query return NTSTATUS
Also use talloc for the result
Autobuild-User: Volker Lendecke <vlendec at samba.org>
Autobuild-Date: Tue Dec 28 18:21:05 CET 2010 on sn-devel-104
(cherry picked from commit 4622812a41eb5ce07dd8f74534217e858743883f)
commit d7c32ae6fcab9205abf86b0d8fd1f92f410ccecf
Author: Volker Lendecke <vl at samba.org>
Date: Tue Dec 28 17:17:04 2010 +0100
s3: AllowDebugChange is gone
(cherry picked from commit 28d997a89056f144de6a7b95af0e54a044c5e5b3)
commit 030f2ff39a64a8d378c1c2a9027e5152e17e83b3
Author: Volker Lendecke <vl at samba.org>
Date: Tue Dec 28 17:05:18 2010 +0100
Fix a crash in libnss_wins
lp_set_parm accesses the case tables
(cherry picked from commit 181cd3281c4f2c53dc507f59d281a2517579cfe1)
commit 073f0023dac2be067f15f29d6efd02491de457ed
Author: Volker Lendecke <vl at samba.org>
Date: Tue Dec 28 12:53:12 2010 +0100
s3: Make node_status_query return NTSTATUS
Also make the result talloc'ed
Autobuild-User: Volker Lendecke <vlendec at samba.org>
Autobuild-Date: Tue Dec 28 13:46:59 CET 2010 on sn-devel-104
(cherry picked from commit 571711431885e8e556822c14b3d117025860bf81)
commit ef6cb55db8457654d5d19d4c4f9d859864d40ca8
Author: Volker Lendecke <vl at samba.org>
Date: Tue Dec 28 11:55:47 2010 +0100
s3: Remove an ancient typedef
(cherry picked from commit e1ab3c3470a7f1159d52ed0c1eacf4a5a7b6bc2b)
commit 522cbb353ff988d3275f4449d97485a42a76d5af
Author: Volker Lendecke <vl at samba.org>
Date: Tue Dec 28 11:48:43 2010 +0100
s3: Fix some typos
(cherry picked from commit b0ff97d8d37957fc34861214b6cbab513072bef1)
commit 80ef0195bd42a3d4fcd1a03e85ea06dc85cee757
Author: Volker Lendecke <vl at samba.org>
Date: Sun Dec 26 16:03:58 2010 +0100
async_send->sendto, async_recv->recvfrom
(cherry picked from commit c4b18bd860bc18529249a8c54c7db6aba2347591)
commit 7371bf53f793e5857c4bb43fdd58e8f121e7007d
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Dec 24 11:54:51 2010 +0100
tdb:tdbtorture: use TEST_DATA_PREFIX for files
metze
Autobuild-User: Stefan Metzmacher <metze at samba.org>
Autobuild-Date: Fri Dec 24 18:17:53 CET 2010 on sn-devel-104
(cherry picked from commit b83672b36c1ea8c35833c40c3919b63809f16624)
commit 8b916ab9203188bd47c8f9afcdb17d183ccd2167
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Dec 24 11:54:03 2010 +0100
tdb:tdbtest: use TEST_DATA_PREFIX for files
metze
(cherry picked from commit d81ceeb9833ec80d7ab21b34e4b3af3d79aeb845)
commit 94d4655d04c02d79e5ce4517a8bf9c4f63719688
Author: Günther Deschner <gd at samba.org>
Date: Thu Dec 23 14:43:10 2010 +0100
testprogs: testspoolss.exe: pretty print FILETIME in driver info 6 and 8.
Guenther
Autobuild-User: Günther Deschner <gd at samba.org>
Autobuild-Date: Thu Dec 23 23:40:21 CET 2010 on sn-devel-104
(cherry picked from commit 821b2a9d1197d927ab6081bcd953a0540888dcf3)
commit 72b35f9a81029c1c336df8a48a7534970d4d89f6
Author: Volker Lendecke <vl at samba.org>
Date: Sun Dec 26 15:00:53 2010 +0100
tevent: More documentation updates
Autobuild-User: Volker Lendecke <vlendec at samba.org>
Autobuild-Date: Sun Dec 26 15:49:59 CET 2010 on sn-devel-104
(cherry picked from commit b2c983149cd498e633c5c17c1d39e10c70fef630)
-----------------------------------------------------------------------
Summary of changes:
lib/async_req/async_sock.c | 91 ++++++++++++++--------
lib/async_req/async_sock.h | 21 +++---
lib/tdb/tools/tdbtest.c | 31 +++++++-
lib/tdb/tools/tdbtorture.c | 38 +++++++--
lib/tevent/tevent.h | 73 ++++++++++++++++++-
nsswitch/wins.c | 17 ++--
source3/client/client.c | 1 -
source3/include/proto.h | 47 ++++++++----
source3/include/smb.h | 4 +-
source3/libsmb/namequery.c | 108 +++++++++++++++-----------
source3/libsmb/smbsock_connect.c | 113 +++++++++++++++++++++------
source3/torture/test_smbsock_any_connect.c | 5 +-
source3/utils/nmblookup.c | 39 ++++++----
source3/web/diagnose.c | 10 ++-
source3/winbindd/winbindd_cm.c | 7 +-
source3/winbindd/winbindd_wins.c | 51 ++++++++-----
testprogs/win32/spoolss/printlib.c | 102 ++++++++++++++++++++++++-
testprogs/win32/spoolss/printlib_proto.h | 2 +
18 files changed, 562 insertions(+), 198 deletions(-)
Changeset truncated at 500 lines:
diff --git a/lib/async_req/async_sock.c b/lib/async_req/async_sock.c
index 18adb42..7ea66f5 100644
--- a/lib/async_req/async_sock.c
+++ b/lib/async_req/async_sock.c
@@ -36,28 +36,29 @@
#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0)
#endif
-struct async_send_state {
+struct sendto_state {
int fd;
const void *buf;
size_t len;
int flags;
+ const struct sockaddr_storage *addr;
+ socklen_t addr_len;
ssize_t sent;
};
-static void async_send_handler(struct tevent_context *ev,
+static void sendto_handler(struct tevent_context *ev,
struct tevent_fd *fde,
uint16_t flags, void *private_data);
-struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- int fd, const void *buf, size_t len,
- int flags)
+struct tevent_req *sendto_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
+ int fd, const void *buf, size_t len, int flags,
+ const struct sockaddr_storage *addr)
{
struct tevent_req *result;
- struct async_send_state *state;
+ struct sendto_state *state;
struct tevent_fd *fde;
- result = tevent_req_create(mem_ctx, &state, struct async_send_state);
+ result = tevent_req_create(mem_ctx, &state, struct sendto_state);
if (result == NULL) {
return result;
}
@@ -65,8 +66,26 @@ struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx,
state->buf = buf;
state->len = len;
state->flags = flags;
+ state->addr = addr;
+
+ switch (addr->ss_family) {
+ case AF_INET:
+ state->addr_len = sizeof(struct sockaddr_in);
+ break;
+#if defined(HAVE_IPV6)
+ case AF_INET6:
+ state->addr_len = sizeof(struct sockaddr_in6);
+ break;
+#endif
+ case AF_UNIX:
+ state->addr_len = sizeof(struct sockaddr_un);
+ break;
+ default:
+ state->addr_len = sizeof(struct sockaddr_storage);
+ break;
+ }
- fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, async_send_handler,
+ fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, sendto_handler,
result);
if (fde == NULL) {
TALLOC_FREE(result);
@@ -75,16 +94,17 @@ struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx,
return result;
}
-static void async_send_handler(struct tevent_context *ev,
+static void sendto_handler(struct tevent_context *ev,
struct tevent_fd *fde,
uint16_t flags, void *private_data)
{
struct tevent_req *req = talloc_get_type_abort(
private_data, struct tevent_req);
- struct async_send_state *state =
- tevent_req_data(req, struct async_send_state);
+ struct sendto_state *state =
+ tevent_req_data(req, struct sendto_state);
- state->sent = send(state->fd, state->buf, state->len, state->flags);
+ state->sent = sendto(state->fd, state->buf, state->len, state->flags,
+ (struct sockaddr *)state->addr, state->addr_len);
if ((state->sent == -1) && (errno == EINTR)) {
/* retry */
return;
@@ -96,10 +116,10 @@ static void async_send_handler(struct tevent_context *ev,
tevent_req_done(req);
}
-ssize_t async_send_recv(struct tevent_req *req, int *perrno)
+ssize_t sendto_recv(struct tevent_req *req, int *perrno)
{
- struct async_send_state *state =
- tevent_req_data(req, struct async_send_state);
+ struct sendto_state *state =
+ tevent_req_data(req, struct sendto_state);
if (tevent_req_is_unix_error(req, perrno)) {
return -1;
@@ -107,27 +127,31 @@ ssize_t async_send_recv(struct tevent_req *req, int *perrno)
return state->sent;
}
-struct async_recv_state {
+struct recvfrom_state {
int fd;
void *buf;
size_t len;
int flags;
+ struct sockaddr_storage *addr;
+ socklen_t *addr_len;
ssize_t received;
};
-static void async_recv_handler(struct tevent_context *ev,
+static void recvfrom_handler(struct tevent_context *ev,
struct tevent_fd *fde,
uint16_t flags, void *private_data);
-struct tevent_req *async_recv_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- int fd, void *buf, size_t len, int flags)
+struct tevent_req *recvfrom_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ int fd, void *buf, size_t len, int flags,
+ struct sockaddr_storage *addr,
+ socklen_t *addr_len)
{
struct tevent_req *result;
- struct async_recv_state *state;
+ struct recvfrom_state *state;
struct tevent_fd *fde;
- result = tevent_req_create(mem_ctx, &state, struct async_recv_state);
+ result = tevent_req_create(mem_ctx, &state, struct recvfrom_state);
if (result == NULL) {
return result;
}
@@ -135,8 +159,10 @@ struct tevent_req *async_recv_send(TALLOC_CTX *mem_ctx,
state->buf = buf;
state->len = len;
state->flags = flags;
+ state->addr = addr;
+ state->addr_len = addr_len;
- fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, async_recv_handler,
+ fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, recvfrom_handler,
result);
if (fde == NULL) {
TALLOC_FREE(result);
@@ -145,17 +171,18 @@ struct tevent_req *async_recv_send(TALLOC_CTX *mem_ctx,
return result;
}
-static void async_recv_handler(struct tevent_context *ev,
+static void recvfrom_handler(struct tevent_context *ev,
struct tevent_fd *fde,
uint16_t flags, void *private_data)
{
struct tevent_req *req = talloc_get_type_abort(
private_data, struct tevent_req);
- struct async_recv_state *state =
- tevent_req_data(req, struct async_recv_state);
+ struct recvfrom_state *state =
+ tevent_req_data(req, struct recvfrom_state);
- state->received = recv(state->fd, state->buf, state->len,
- state->flags);
+ state->received = recvfrom(state->fd, state->buf, state->len,
+ state->flags, (struct sockaddr *)state->addr,
+ state->addr_len);
if ((state->received == -1) && (errno == EINTR)) {
/* retry */
return;
@@ -171,10 +198,10 @@ static void async_recv_handler(struct tevent_context *ev,
tevent_req_done(req);
}
-ssize_t async_recv_recv(struct tevent_req *req, int *perrno)
+ssize_t recvfrom_recv(struct tevent_req *req, int *perrno)
{
- struct async_recv_state *state =
- tevent_req_data(req, struct async_recv_state);
+ struct recvfrom_state *state =
+ tevent_req_data(req, struct recvfrom_state);
if (tevent_req_is_unix_error(req, perrno)) {
return -1;
diff --git a/lib/async_req/async_sock.h b/lib/async_req/async_sock.h
index e7ddff8..8d98886 100644
--- a/lib/async_req/async_sock.h
+++ b/lib/async_req/async_sock.h
@@ -27,16 +27,17 @@
#include <talloc.h>
#include <tevent.h>
-struct tevent_req *async_send_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- int fd, const void *buf, size_t len,
- int flags);
-ssize_t async_send_recv(struct tevent_req *req, int *perrno);
-
-struct tevent_req *async_recv_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- int fd, void *buf, size_t len, int flags);
-ssize_t async_recv_recv(struct tevent_req *req, int *perrno);
+struct tevent_req *sendto_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
+ int fd, const void *buf, size_t len, int flags,
+ const struct sockaddr_storage *addr);
+ssize_t sendto_recv(struct tevent_req *req, int *perrno);
+
+struct tevent_req *recvfrom_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ int fd, void *buf, size_t len, int flags,
+ struct sockaddr_storage *addr,
+ socklen_t *addr_len);
+ssize_t recvfrom_recv(struct tevent_req *req, int *perrno);
struct tevent_req *async_connect_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
diff --git a/lib/tdb/tools/tdbtest.c b/lib/tdb/tools/tdbtest.c
index 416bc50..44c78ef 100644
--- a/lib/tdb/tools/tdbtest.c
+++ b/lib/tdb/tools/tdbtest.c
@@ -215,16 +215,38 @@ static void merge_test(void)
tdb_delete(db, key);
}
+static char *test_path(const char *filename)
+{
+ const char *prefix = getenv("TEST_DATA_PREFIX");
+
+ if (prefix) {
+ char *path = NULL;
+ int ret;
+
+ ret = asprintf(&path, "%s/%s", prefix, filename);
+ if (ret == -1) {
+ return NULL;
+ }
+ return path;
+ }
+
+ return strdup(filename);
+}
+
int main(int argc, const char *argv[])
{
int i, seed=0;
int loops = 10000;
int num_entries;
- char test_gdbm[] = "test.gdbm";
+ char test_gdbm[1] = "test.gdbm";
+ char *test_tdb;
- unlink("test.gdbm");
+ test_gdbm[0] = test_path("test.gdbm");
+ test_tdb = test_path("test.tdb");
- db = tdb_open("test.tdb", 0, TDB_CLEAR_IF_FIRST,
+ unlink(test_gdbm[0]);
+
+ db = tdb_open(test_tdb, 0, TDB_CLEAR_IF_FIRST,
O_RDWR | O_CREAT | O_TRUNC, 0600);
gdbm = gdbm_open(test_gdbm, 512, GDBM_WRITER|GDBM_NEWDB|GDBM_FAST,
0600, NULL);
@@ -261,5 +283,8 @@ static void merge_test(void)
tdb_close(db);
gdbm_close(gdbm);
+ free(test_gdbm[0]);
+ free(test_tdb);
+
return 0;
}
diff --git a/lib/tdb/tools/tdbtorture.c b/lib/tdb/tools/tdbtorture.c
index 79fe3cd..64c5043 100644
--- a/lib/tdb/tools/tdbtorture.c
+++ b/lib/tdb/tools/tdbtorture.c
@@ -228,9 +228,9 @@ static void send_count_and_suicide(int sig)
kill(getpid(), SIGUSR2);
}
-static int run_child(int i, int seed, unsigned num_loops, unsigned start)
+static int run_child(const char *filename, int i, int seed, unsigned num_loops, unsigned start)
{
- db = tdb_open_ex("torture.tdb", hash_size, TDB_DEFAULT,
+ db = tdb_open_ex(filename, hash_size, TDB_DEFAULT,
O_RDWR | O_CREAT, 0600, &log_ctx, NULL);
if (!db) {
fatal("db open failed");
@@ -270,6 +270,24 @@ static int run_child(int i, int seed, unsigned num_loops, unsigned start)
return (error_count < 100 ? error_count : 100);
}
+static char *test_path(const char *filename)
+{
+ const char *prefix = getenv("TEST_DATA_PREFIX");
+
+ if (prefix) {
+ char *path = NULL;
+ int ret;
+
+ ret = asprintf(&path, "%s/%s", prefix, filename);
+ if (ret == -1) {
+ return NULL;
+ }
+ return path;
+ }
+
+ return strdup(filename);
+}
+
int main(int argc, char * const *argv)
{
int i, seed = -1;
@@ -280,6 +298,7 @@ int main(int argc, char * const *argv)
pid_t *pids;
int kill_random = 0;
int *done;
+ char *test_tdb;
log_ctx.log_fn = tdb_log;
@@ -308,7 +327,9 @@ int main(int argc, char * const *argv)
}
}
- unlink("torture.tdb");
+ test_tdb = test_path("torture.tdb");
+
+ unlink(test_tdb);
if (seed == -1) {
seed = (getpid() + time(NULL)) & 0x7FFFFFFF;
@@ -316,7 +337,7 @@ int main(int argc, char * const *argv)
if (num_procs == 1 && !kill_random) {
/* Don't fork for this case, makes debugging easier. */
- error_count = run_child(0, seed, num_loops, 0);
+ error_count = run_child(test_tdb, 0, seed, num_loops, 0);
goto done;
}
@@ -336,7 +357,7 @@ int main(int argc, char * const *argv)
printf("Testing with %d processes, %d loops, %d hash_size, seed=%d%s\n",
num_procs, num_loops, hash_size, seed, always_transaction ? " (all within transactions)" : "");
}
- exit(run_child(i, seed, num_loops, 0));
+ exit(run_child(test_tdb, i, seed, num_loops, 0));
}
}
@@ -389,8 +410,8 @@ int main(int argc, char * const *argv)
}
pids[j] = fork();
if (pids[j] == 0)
- exit(run_child(j, seed, num_loops,
- done[j]));
+ exit(run_child(test_tdb, j, seed,
+ num_loops, done[j]));
printf("Restarting child %i for %u-%u\n",
j, done[j], num_loops);
continue;
@@ -414,7 +435,7 @@ int main(int argc, char * const *argv)
done:
if (error_count == 0) {
- db = tdb_open_ex("torture.tdb", hash_size, TDB_DEFAULT,
+ db = tdb_open_ex(test_tdb, hash_size, TDB_DEFAULT,
O_RDWR, 0, &log_ctx, NULL);
if (!db) {
fatal("db open failed");
@@ -427,5 +448,6 @@ done:
printf("OK\n");
}
+ free(test_tdb);
return error_count;
}
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h
index 1c01a63..d67e2b0 100644
--- a/lib/tevent/tevent.h
+++ b/lib/tevent/tevent.h
@@ -520,9 +520,65 @@ int tevent_set_debug_stderr(struct tevent_context *ev);
* requests are much easier to compose than the low-level event
* handlers called from tevent_add_fd.
*
+ * A lot of the simplicity tevent_req has brought to the notoriously
+ * hairy async programming came via a set of conventions that every
+ * async computation programmed should follow. One central piece of
+ * these conventions is the naming of routines and variables.
+ *
+ * Every async computation needs a name (sensibly called "computation"
+ * down from here). From this name quite a few naming conventions are
+ * derived.
+ *
+ * Every computation that requires local state needs a
+ * @code
+ * struct computation_state {
+ * int local_var;
+ * };
+ * @endcode
+ * Even if no local variables are required, such a state struct should
+ * be created containing a dummy variable. Quite a few helper
+ * functions and macros (for example tevent_req_create()) assume such
+ * a state struct.
+ *
* An async computation is started by a computation_send
* function. When it is finished, its result can be received by a
- * computation_recv function.
+ * computation_recv function. For an example how to set up an async
+ * computation, see the code example in the documentation for
+ * tevent_req_create() and tevent_req_post(). The prototypes for _send
+ * and _recv functions should follow some conventions:
+ *
+ * @code
+ * struct tevent_req *computation_send(TALLOC_CTX *mem_ctx,
+ * struct tevent_req *ev,
+ * ... further args);
+ * int computation_recv(struct tevent_req *req, ... further output args);
+ * @endcode
+ *
+ * The "int" result of computation_recv() depends on the result the
+ * sync version of the function would have, "int" is just an example
+ * here.
+ *
+ * Another important piece of the conventions is that the program flow
+ * is interrupted as little as possible. Because a blocking
+ * sub-computation requires that the flow needs to continue in a
+ * separate function that is the logical sequel of some computation,
+ * it should lexically follow sending off the blocking
+ * sub-computation. Setting the callback function via
+ * tevent_req_set_callback() requires referencing a function lexically
+ * below the call to tevent_req_set_callback(), forward declarations
+ * are required. A lot of the async computations thus begin with a
+ * sequence of declarations such as
+ *
+ * @code
+ * static void computation_step1_done(struct tevent_req *subreq);
+ * static void computation_step2_done(struct tevent_req *subreq);
+ * static void computation_step3_done(struct tevent_req *subreq);
+ * @endcode
+ *
+ * It really helps readability a lot to do these forward declarations,
+ * because the lexically sequential program flow makes the async
+ * computations almost as clear to read as a normal, sync program
+ * flow.
*
* It is up to the user of the async computation to talloc_free it
* after it has finished. If an async computation should be aborted,
@@ -587,6 +643,9 @@ typedef void (*tevent_req_fn)(struct tevent_req *req);
/**
* @brief Set an async request callback.
*
+ * See the documentation of tevent_req_post() for an example how this
+ * is supposed to be used.
+ *
* @param[in] req The async request to set the callback.
*
* @param[in] fn The callback function to set.
@@ -642,6 +701,10 @@ void *tevent_req_callback_data_void(struct tevent_req *req);
/**
* @brief Get the private data from a tevent request structure.
*
+ * When the tevent_req has been created by tevent_req_create, the
+ * result of tevent_req_data() is the state variable created by
+ * tevent_req_create() as a child of the req.
+ *
* @param[in] req The structure to get the private data from.
*
* @param[in] type The type of the private data
@@ -788,6 +851,13 @@ bool _tevent_req_cancel(struct tevent_req *req, const char *location);
* req = tevent_req_create(mem_ctx, &state, struct computation_state);
* @endcode
*
+ * Tevent_req_create() creates the state variable as a talloc child of
+ * its result. The state variable should be used as the talloc parent
+ * for all temporary variables that are allocated during the async
+ * computation. This way, when the user of the async computation frees
+ * the request, the state as a talloc child will be free'd along with
+ * all the temporary variables hanging off the state.
+ *
* @param[in] mem_ctx The memory context for the result.
* @param[in] pstate Pointer to the private request state.
* @param[in] type The name of the request.
@@ -949,6 +1019,7 @@ bool _tevent_req_nomem(const void *p,
* if (tevent_req_nomem(subreq, req)) {
* return tevent_req_post(req, ev);
* }
+ * tevent_req_set_callback(subreq, computation_done, req);
* return req;
* }
--
Samba Shared Repository
More information about the samba-cvs
mailing list