summaryrefslogtreecommitdiffstats
path: root/source3/lib/unix_msg/test_source.c
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2014-02-24 11:48:16 +0000
committerJeremy Allison <jra@samba.org>2014-04-23 22:33:08 +0200
commit6dcf2c7eab0f39a17f22b09df94e5fcdac8726d1 (patch)
tree1331e1c62bb2d40e552dd6b1e48f851d84bf4d58 /source3/lib/unix_msg/test_source.c
parentbafdecdf1fb110b02796a6357b1501777195f9d9 (diff)
downloadsamba-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.c79
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;
+}