diff options
author | Volker Lendecke <vl@samba.org> | 2014-02-24 11:48:16 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2014-04-23 22:33:08 +0200 |
commit | 6dcf2c7eab0f39a17f22b09df94e5fcdac8726d1 (patch) | |
tree | 1331e1c62bb2d40e552dd6b1e48f851d84bf4d58 /source3/lib/unix_msg/test_source.c | |
parent | bafdecdf1fb110b02796a6357b1501777195f9d9 (diff) | |
download | samba-6dcf2c7eab0f39a17f22b09df94e5fcdac8726d1.tar.gz samba-6dcf2c7eab0f39a17f22b09df94e5fcdac8726d1.tar.xz samba-6dcf2c7eab0f39a17f22b09df94e5fcdac8726d1.zip |
lib: Add unix_msg
This is a messaging layer based on unix domain datagram sockets.
Sending to an idle socket is just one single nonblocking sendmsg call. If the
recv queue is full, we start a background thread to do a blocking call. The
source4 based imessaging uses a polling fallback. In a situation where
thousands of senders beat one single blocked socket, this will generate load on
the system due to the constant polling. This does not happen with a threaded
blocking send call.
The threaded approach has another advantage: We save become_root() calls on the
retries. The access checks are done when the blocking socket is connected, the
threaded blocking send call does not check permissions anymore.
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3/lib/unix_msg/test_source.c')
-rw-r--r-- | source3/lib/unix_msg/test_source.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/source3/lib/unix_msg/test_source.c b/source3/lib/unix_msg/test_source.c new file mode 100644 index 00000000000..bfafee1fd33 --- /dev/null +++ b/source3/lib/unix_msg/test_source.c @@ -0,0 +1,79 @@ +#include "replace.h" +#include "unix_msg.h" +#include "poll_funcs/poll_funcs_tevent.h" +#include "tevent.h" + +int main(int argc, const char *argv[]) +{ + struct poll_funcs funcs; + struct unix_msg_ctx **ctxs; + struct tevent_context *ev; + struct iovec iov; + int ret; + unsigned i; + unsigned num_ctxs = 1; + + if (argc < 2) { + fprintf(stderr, "Usage: %s <sockname> [num_contexts]\n", argv[0]); + return 1; + } + if (argc > 2) { + num_ctxs = atoi(argv[2]); + } + + ev = tevent_context_init(NULL); + if (ev == NULL) { + perror("tevent_context_init failed"); + return 1; + } + poll_funcs_init_tevent(&funcs, ev); + + ctxs = talloc_array(ev, struct unix_msg_ctx *, num_ctxs); + if (ctxs == NULL) { + fprintf(stderr, "talloc failed\n"); + return 1; + } + + for (i=0; i<num_ctxs; i++) { + ret = unix_msg_init(NULL, &funcs, 256, 1, NULL, NULL, + &ctxs[i]); + if (ret != 0) { + fprintf(stderr, "unix_msg_init failed: %s\n", + strerror(ret)); + return 1; + } + } + + iov.iov_base = &i; + iov.iov_len = sizeof(i); + + for (i=0; i<num_ctxs; i++) { + unsigned j; + + for (j=0; j<100000; j++) { + ret = unix_msg_send(ctxs[i], argv[1], &iov, 1); + if (ret != 0) { + fprintf(stderr, "unix_msg_send failed: %s\n", + strerror(ret)); + return 1; + } + } + } + + while (true) { + ret = tevent_loop_once(ev); + if (ret == -1) { + fprintf(stderr, "tevent_loop_once failed: %s\n", + strerror(errno)); + exit(1); + } + } + + for (i=0; i<num_ctxs; i++) { + unix_msg_free(ctxs[i]); + } + + talloc_free(ev); + + return 0; +} |