1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-04 17:47:26 +03:00
Andrew Tridgell bf1ffa283c r7294: implemented the irpc messaging system. This is the core of the
management system I proposed on samba-technical a couple of days
ago. Essentially it is a very lightweight way for any code in Samba to
make IDL based rpc calls to anywhere else in the code, without the
client or server having to go to the trouble of setting up a full rpc
service.

It can be used with any of our existing IDL, but I expect it will
mostly be used for a new set of Samba specific management calls.

The LOCAL-IRPC torture test demonstrates how it can be used by calling
the echo_AddOne() call over this transport.
(This used to be commit 3d589a09954eb8b318f567e1150b0c27412fb942)
2007-10-10 13:17:37 -05:00

153 lines
3.6 KiB
C

/*
Unix SMB/CIFS implementation.
local test for messaging code
Copyright (C) Andrew Tridgell 2004
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 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "system/filesys.h"
#include "lib/events/events.h"
#include "lib/messaging/irpc.h"
enum {MY_PING=1000, MY_PONG, MY_EXIT};
static void ping_message(struct messaging_context *msg, void *private,
uint32_t msg_type, uint32_t src, DATA_BLOB *data)
{
NTSTATUS status;
status = messaging_send(msg, src, MY_PONG, data);
if (!NT_STATUS_IS_OK(status)) {
printf("pong failed - %s\n", nt_errstr(status));
}
}
static void pong_message(struct messaging_context *msg, void *private,
uint32_t msg_type, uint32_t src, DATA_BLOB *data)
{
int *count = private;
(*count)++;
}
static void exit_message(struct messaging_context *msg, void *private,
uint32_t msg_type, uint32_t src, DATA_BLOB *data)
{
talloc_free(private);
exit(0);
}
/*
test ping speed
*/
static BOOL test_ping_speed(TALLOC_CTX *mem_ctx)
{
struct event_context *ev;
struct messaging_context *msg_ctx;
struct messaging_context *msg_ctx2;
int ping_count = 0;
int pong_count = 0;
BOOL ret = True;
struct timeval tv;
lp_set_cmdline("lock dir", "lockdir.tmp");
ev = event_context_init(mem_ctx);
msg_ctx2 = messaging_init(mem_ctx, 1, ev);
if (!msg_ctx2) {
exit(1);
}
messaging_register(msg_ctx2, NULL, MY_PING, ping_message);
messaging_register(msg_ctx2, mem_ctx, MY_EXIT, exit_message);
msg_ctx = messaging_init(mem_ctx, 2, ev);
if (!msg_ctx) {
printf("messaging_init() failed\n");
return False;
}
messaging_register(msg_ctx, &pong_count, MY_PONG, pong_message);
tv = timeval_current();
printf("Sending pings for 10 seconds\n");
while (timeval_elapsed(&tv) < 10.0) {
DATA_BLOB data;
NTSTATUS status1, status2;
data.data = discard_const_p(uint8_t, "testing");
data.length = strlen((const char *)data.data);
status1 = messaging_send(msg_ctx, 1, MY_PING, &data);
status2 = messaging_send(msg_ctx, 1, MY_PING, NULL);
if (!NT_STATUS_IS_OK(status1)) {
printf("msg1 failed - %s\n", nt_errstr(status1));
}
if (!NT_STATUS_IS_OK(status2)) {
printf("msg2 failed - %s\n", nt_errstr(status2));
}
ping_count += 2;
while (ping_count > pong_count + 20) {
event_loop_once(ev);
}
}
printf("waiting for %d remaining replies (done %d)\n",
ping_count - pong_count, pong_count);
while (timeval_elapsed(&tv) < 30 && pong_count < ping_count) {
event_loop_once(ev);
}
printf("sending exit\n");
messaging_send(msg_ctx, 1, MY_EXIT, NULL);
if (ping_count != pong_count) {
printf("ping test failed! received %d, sent %d\n",
pong_count, ping_count);
ret = False;
}
printf("ping rate of %.0f messages/sec\n",
(ping_count+pong_count)/timeval_elapsed(&tv));
talloc_free(msg_ctx);
talloc_free(ev);
return ret;
}
BOOL torture_local_messaging(void)
{
TALLOC_CTX *mem_ctx = talloc_init("torture_local_messaging");
BOOL ret = True;
ret &= test_ping_speed(mem_ctx);
talloc_free(mem_ctx);
return True;
}