diff --git a/runtime/include/sandbox.h b/runtime/include/sandbox.h index e274494..99bccc4 100644 --- a/runtime/include/sandbox.h +++ b/runtime/include/sandbox.h @@ -58,6 +58,7 @@ struct sandbox { struct io_handle handles[SBOX_MAX_OPEN]; struct sockaddr client; //client requesting connection! + uv_udp_t clientuv; //using uv for client request on target runtime thread/core. char *read_buf; ssize_t read_len, read_size; @@ -139,7 +140,7 @@ void *sandbox_run_func(void *data); struct sandbox *sandbox_schedule(void); void sandbox_block(void); void sandbox_wakeup(sandbox_t *sb); -void sandbox_response(struct sandbox *sb); +void sandbox_response(void); // should be the entry-point for each sandbox so it can do per-sandbox mem/etc init. // should have been called with stack allocated and sandbox_current() set! diff --git a/runtime/src/module.c b/runtime/src/module.c index 5511366..3c4582e 100644 --- a/runtime/src/module.c +++ b/runtime/src/module.c @@ -50,6 +50,7 @@ done: static void module_io_init(struct module *m) { + // TODO: USE_UVIO vs USE_SYSCALL! int status; status = uv_udp_init(uv_default_loop(), &m->udpsrv); diff --git a/runtime/src/runtime.c b/runtime/src/runtime.c index f231f18..c15e515 100644 --- a/runtime/src/runtime.c +++ b/runtime/src/runtime.c @@ -227,6 +227,7 @@ sandbox_exit(void) struct sandbox *curr = sandbox_current(); assert(curr); + sandbox_response(); fprintf(stderr, "(%d,%lu) %s: %p, %s exit\n", sched_getcpu(), pthread_self(), __func__, curr, curr->mod->name); softint_disable(); @@ -234,7 +235,6 @@ sandbox_exit(void) curr->state = SANDBOX_RETURNED; // free resources from "main function execution", as stack still in use. sandbox_local_end(curr); - sandbox_response(curr); struct sandbox *n = sandbox_schedule(); softint_enable(); sandbox_switch(n); diff --git a/runtime/src/sandbox.c b/runtime/src/sandbox.c index a208e70..ba35221 100644 --- a/runtime/src/sandbox.c +++ b/runtime/src/sandbox.c @@ -4,6 +4,7 @@ #include #include #include +#include static inline void sandbox_args_setup(i32 argc) @@ -31,6 +32,27 @@ sandbox_args_setup(i32 argc) } } +static void +sandbox_uvio_init(struct sandbox *c) +{ +#ifndef STANDALONE + int ret = uv_udp_init(runtime_uvio(), &c->clientuv); + assert(ret == 0); + //ret = uv_udp_bind(&c->clientuv, (const struct sockaddr *)&c->mod->srvaddr, 0); + //assert(ret >= 0); + + //ret = uv_udp_connect(&c->clientuv, &c->client); + //assert(ret == 0); + //c->clientuv.data = (void *)c; + //struct sockaddr_in addr; + //int len = sizeof(addr); + //ret = uv_udp_getpeername(&c->clientuv, &addr, &len); + //assert(ret == 0); + //printf("Peer's IP address is: %s\n", inet_ntoa(addr.sin_addr)); + //printf("Peer's port is: %d\n", (int) ntohs(addr.sin_port)); +#endif +} + void sandbox_entry(void) { @@ -54,6 +76,8 @@ sandbox_entry(void) f = io_handle_open(2); assert(f == 2); + sandbox_uvio_init(curr); + alloc_linear_memory(); // perhaps only initialized for the first instance? or TODO! @@ -100,19 +124,40 @@ sandbox_alloc(struct module *mod, char *args, const struct sockaddr *addr) } void -sandbox_response(struct sandbox *sb) +sandbox_udp_send_callback(uv_udp_send_t *req, int status) { + struct sandbox *c = req->data; + c->retval = status; + + sandbox_wakeup(c); +} + +void +sandbox_response(void) +{ + struct sandbox *sb = sandbox_current(); // send response. #ifndef STANDALONE - int sock = -1; - char resp[SBOX_RESP_STRSZ] = { 0 }; - int ret = uv_fileno((uv_handle_t *)&sb->mod->udpsrv, &sock); - assert(ret == 0); + int sock = -1, ret; + char resp[SBOX_RESP_STRSZ] = { 0 }; // sends return value only for now! - sprintf(resp, "%d", sb->retval); + sprintf(resp, "%d", sb->retval); +#ifdef USE_SYSCALL + // FIXME, with USE_SYSCALL, we should not be using uv at all. + int ret = uv_fileno((uv_handle_t *)&sb->mod->udpsrv, &sock); + assert(ret == 0); // using system call here because uv_udp_t is in the "module listener thread"'s loop, cannot access here. also dnot want to mess with cross-core/cross-thread uv loop states or structures. - ret = sendto(sock, resp, strlen(resp), 0, &sb->client, sizeof(struct sockaddr)); - assert(ret == strlen(resp)); + ret = sendto(sock, resp, strlen(resp), 0, &sb->client, sizeof(struct sockaddr)); + assert(ret == strlen(resp)); +#elif USE_UVIO + uv_udp_send_t req = { .data = sb, }; + uv_buf_t b = uv_buf_init(resp, strlen(resp)); + ret = uv_udp_send(&req, &sb->clientuv, &b, 1, &sb->client, sandbox_udp_send_callback); + assert(ret == 0); + sandbox_block(); +#else + assert(0); +#endif #endif }