2011-01-05 18:08:13 +00:00
|
|
|
/* Copyright (C) 2010, 2011 Tony Garnock-Jones. All rights reserved. */
|
2010-12-27 21:56:42 +00:00
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
2011-01-02 18:40:36 +00:00
|
|
|
#include <signal.h>
|
2010-12-27 21:56:42 +00:00
|
|
|
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <ucontext.h>
|
|
|
|
|
2011-01-01 22:29:38 +00:00
|
|
|
#include <assert.h>
|
|
|
|
|
2010-12-27 21:56:42 +00:00
|
|
|
typedef unsigned char u_char;
|
|
|
|
#include <event.h>
|
|
|
|
|
|
|
|
#include "cmsg_private.h"
|
|
|
|
#include "harness.h"
|
|
|
|
#include "net.h"
|
2010-12-30 04:56:31 +00:00
|
|
|
#include "ref.h"
|
|
|
|
#include "sexp.h"
|
|
|
|
#include "hashtable.h"
|
|
|
|
#include "node.h"
|
2011-01-02 02:14:37 +00:00
|
|
|
#include "queue.h"
|
2011-01-02 22:56:11 +00:00
|
|
|
#include "direct.h"
|
2011-01-02 23:14:51 +00:00
|
|
|
#include "fanout.h"
|
2011-01-03 03:46:48 +00:00
|
|
|
#include "meta.h"
|
2010-12-30 04:56:31 +00:00
|
|
|
|
2011-01-01 22:29:38 +00:00
|
|
|
#define WANT_CONSOLE_LISTENER 1
|
|
|
|
|
2010-12-30 04:56:31 +00:00
|
|
|
static void factory_handle_message(node_t *n, sexp_t *m) {
|
2011-01-02 02:13:21 +00:00
|
|
|
size_t msglen = sexp_length(m);
|
|
|
|
sexp_t *args;
|
|
|
|
cmsg_bytes_t selector;
|
|
|
|
|
|
|
|
if (msglen == 0 || !sexp_stringp(sexp_head(m))) {
|
|
|
|
warn("Invalid message in factory\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
selector = sexp_data(sexp_head(m));
|
|
|
|
args = sexp_tail(m);
|
|
|
|
|
2011-01-03 03:08:30 +00:00
|
|
|
if ((msglen == 5) && !cmsg_bytes_cmp(selector, cmsg_cstring_bytes("create"))) {
|
2011-01-02 02:13:21 +00:00
|
|
|
sexp_t *classname = sexp_listref(args, 0);
|
|
|
|
sexp_t *ctor_arg = sexp_listref(args, 1);
|
|
|
|
sexp_t *reply_sink = sexp_listref(args, 2);
|
|
|
|
sexp_t *reply_name = sexp_listref(args, 3);
|
|
|
|
if (sexp_stringp(classname) && sexp_stringp(reply_sink) && sexp_stringp(reply_name)) {
|
|
|
|
cmsg_bytes_t classname_bytes = sexp_data(classname);
|
|
|
|
node_class_t *nc = lookup_node_class(classname_bytes);
|
|
|
|
if (nc == NULL) {
|
|
|
|
warn("Node class not found <<%.*s>>\n", classname_bytes.len, classname_bytes.bytes);
|
|
|
|
} else {
|
2011-01-02 16:49:56 +00:00
|
|
|
sexp_t *error = NULL;
|
|
|
|
sexp_t *reply;
|
|
|
|
if (new_node(nc, ctor_arg, &error) != NULL) {
|
|
|
|
reply = sexp_cons(sexp_cstring("create-ok"), NULL);
|
|
|
|
} else {
|
|
|
|
reply = sexp_cons(sexp_cstring("create-failed"), sexp_cons(error, NULL));
|
2011-01-02 02:13:21 +00:00
|
|
|
}
|
2011-01-02 16:49:56 +00:00
|
|
|
INCREF(reply);
|
2011-01-02 18:58:18 +00:00
|
|
|
post_node(sexp_data(reply_sink), sexp_data(reply_name), reply, sexp_empty_bytes);
|
2011-01-02 16:49:56 +00:00
|
|
|
DECREF(reply, sexp_destructor);
|
2011-01-02 02:13:21 +00:00
|
|
|
}
|
|
|
|
}
|
2011-01-03 03:08:30 +00:00
|
|
|
return;
|
2011-01-02 02:13:21 +00:00
|
|
|
}
|
2011-01-03 03:08:30 +00:00
|
|
|
|
|
|
|
warn("Message not understood in factory; selector <<%.*s>>, length %u\n",
|
|
|
|
selector.len, selector.bytes,
|
|
|
|
msglen);
|
2010-12-30 04:56:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static node_class_t factory_class = {
|
|
|
|
.name = "factory",
|
2011-01-02 16:49:56 +00:00
|
|
|
.extend = NULL,
|
|
|
|
.destroy = NULL,
|
2010-12-30 04:56:31 +00:00
|
|
|
.handle_message = factory_handle_message
|
|
|
|
};
|
|
|
|
|
|
|
|
static void init_factory(void) {
|
2011-01-02 16:49:56 +00:00
|
|
|
bind_node(cmsg_cstring_bytes("factory"), new_node(&factory_class, NULL, NULL));
|
2010-12-30 04:56:31 +00:00
|
|
|
}
|
2010-12-27 21:56:42 +00:00
|
|
|
|
2011-01-01 22:29:38 +00:00
|
|
|
#if WANT_CONSOLE_LISTENER
|
2010-12-30 05:32:29 +00:00
|
|
|
static void console_listener(void *arg) {
|
|
|
|
IOHandle *in_handle = new_iohandle(0);
|
|
|
|
while (1) {
|
|
|
|
cmsg_bytes_t buf = iohandle_readwait(in_handle, 1);
|
2011-01-02 19:51:13 +00:00
|
|
|
if (buf.len == 0) break;
|
2010-12-30 05:32:29 +00:00
|
|
|
iohandle_drain(in_handle, buf.len);
|
|
|
|
}
|
|
|
|
delete_iohandle(in_handle);
|
|
|
|
interrupt_harness();
|
|
|
|
}
|
2011-01-01 22:29:38 +00:00
|
|
|
#endif
|
2010-12-30 05:32:29 +00:00
|
|
|
|
2010-12-27 21:56:42 +00:00
|
|
|
int main(int argc, char *argv[]) {
|
2011-01-05 18:08:13 +00:00
|
|
|
info("cmsg ALPHA, Copyright (C) 2010, 2011 Tony Garnock-Jones. All rights reserved.\n");
|
2010-12-27 21:56:42 +00:00
|
|
|
event_init();
|
2011-01-02 18:40:36 +00:00
|
|
|
signal(SIGPIPE, SIG_IGN); /* avoid EPIPE when connections drop unexpectedly */
|
2010-12-27 21:56:42 +00:00
|
|
|
info("Using libevent version %s\n", event_get_version());
|
2011-01-02 18:58:18 +00:00
|
|
|
init_sexp();
|
2010-12-30 04:56:31 +00:00
|
|
|
init_node();
|
|
|
|
init_factory();
|
2011-01-02 02:14:37 +00:00
|
|
|
init_queue();
|
2011-01-02 22:56:11 +00:00
|
|
|
init_direct();
|
2011-01-02 23:14:51 +00:00
|
|
|
init_fanout();
|
2011-01-03 03:46:48 +00:00
|
|
|
init_meta();
|
2011-01-01 22:29:38 +00:00
|
|
|
#if WANT_CONSOLE_LISTENER
|
2010-12-30 05:32:29 +00:00
|
|
|
spawn(console_listener, NULL);
|
2011-01-01 22:29:38 +00:00
|
|
|
#endif
|
2010-12-27 21:56:42 +00:00
|
|
|
start_net(5671);
|
|
|
|
boot_harness();
|
2011-01-02 18:58:18 +00:00
|
|
|
done_sexp();
|
2010-12-27 21:56:42 +00:00
|
|
|
return 0;
|
|
|
|
}
|