/* Copyright (C) 2010 Tony Garnock-Jones. All rights reserved. */ #include #include #include #include #include #include typedef unsigned char u_char; #include #include "cmsg_private.h" #include "harness.h" #include "net.h" #include "ref.h" #include "sexp.h" #include "hashtable.h" #include "node.h" #include "queue.h" #define WANT_CONSOLE_LISTENER 1 static node_t *factory_construct(node_class_t *nc, sexp_t *args) { return malloc(sizeof(node_t)); } static void factory_handle_message(node_t *n, sexp_t *m) { 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); if ((msglen == 5) && !cmsg_bytes_cmp(selector, cmsg_cstring_bytes("create"))) { 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 { new_node(nc, ctor_arg); { sexp_t *createok = sexp_cons(sexp_bytes(cmsg_cstring_bytes("create-ok")), NULL); INCREF(createok); post_node(sexp_data(reply_sink), sexp_data(reply_name), createok); DECREF(createok, sexp_destructor); } } } } else { warn("Message not understood in factory; selector <<%.*s>>, length %u\n", selector.len, selector.bytes, msglen); } } static node_class_t factory_class = { .name = "factory", .construct = factory_construct, .destroy = (node_destructor_fn_t) free, .handle_message = factory_handle_message }; static void init_factory(void) { bind_node(cmsg_cstring_bytes("factory"), new_node(&factory_class, NULL)); } #if WANT_CONSOLE_LISTENER static void console_listener(void *arg) { IOHandle *in_handle = new_iohandle(0); while (1) { cmsg_bytes_t buf = iohandle_readwait(in_handle, 1); if (in_handle->error_kind) break; iohandle_drain(in_handle, buf.len); } delete_iohandle(in_handle); interrupt_harness(); } #endif int main(int argc, char *argv[]) { info("cmsg, Copyright (C) 2010 Tony Garnock-Jones. All rights reserved.\n"); event_init(); info("Using libevent version %s\n", event_get_version()); init_node(); init_factory(); init_queue(); #if WANT_CONSOLE_LISTENER spawn(console_listener, NULL); #endif start_net(5671); boot_harness(); #ifndef NDEBUG release_sexp_cache(); #endif return 0; }