void r_state_free (RState* r) { r->last_error = R_UNDEFINED; r->current_input_port = R_UNDEFINED; r->current_output_port = R_UNDEFINED; r->current_error_port = R_UNDEFINED; vm_finish (r); gc_finish (r); r_free (r, r); }
void run_worker() { while (true) { /* Select among controller port, and connections to routers */ FD_ZERO(&cset); maxcfd = 0; add_cfd(controller_fd); unsigned ridx; for (ridx = 0; ridx < nrouters; ridx++) add_cfd(router_fd_array[ridx]); buf_select(maxcfd+1, &cset, NULL, NULL, NULL); int fd; for (fd = 0; fd <= maxcfd; fd++) { if (!FD_ISSET(fd, &cset)) continue; bool eof; chunk_ptr msg = chunk_read(fd, &eof); if (eof) { /* Unexpected EOF */ if (fd == controller_fd) { err(true, "Unexpected EOF from controller (fatal)"); } else { err(false, "Unexpected EOF from router with fd %d (shutting down)", fd); finish_cmd(); exit(0); } close(fd); continue; } if (msg == NULL) { err(false, "Could not read chunk from fd %d (ignored)", fd); continue; } word_t h = chunk_get_word(msg, 0); /* Rely on fact that following message fields in same location for both single and double-word headers */ unsigned code = msg_get_header_code(h); unsigned agent = msg_get_header_agent(h); unsigned opcode = msg_get_header_opcode(h); if (fd == controller_fd) { /* Message from controller */ switch(code) { case MSG_KILL: chunk_free(msg); #if RPT >= 1 report(1, "Received kill message from controller"); #endif quit_agent(0, NULL); return; case MSG_DO_FLUSH: chunk_free(msg); #if RPT >= 5 report(5, "Received flush message from controller"); #endif if (flush_helper) { chunk_ptr msg = flush_helper(); if (!msg) break; if (chunk_write(controller_fd, msg)) { #if RPT >= 5 report(5, "Sent statistics information to controller"); #endif } else { err(false, "Failed to send statistics information to controller"); } chunk_free(msg); } break; case MSG_CLIOP_DATA: report(5, "Received client operation data. Agent = %u", agent); word_t *data = &msg->words[1]; unsigned nword = msg->length - 1; if (gop_start_helper) gop_start_helper(agent, opcode, nword, data); chunk_free(msg); chunk_ptr rmsg = msg_new_cliop_ack(agent); if (chunk_write(controller_fd, rmsg)) { #if RPT >= 5 report(5, "Acknowledged client operation data. Agent = %u", agent); #endif } else { err(false, "Failed to acknowledge client operation data. Agent = %u", agent); } chunk_free(rmsg); break; case MSG_CLIOP_ACK: #if RPT >= 5 report(5, "Received client operation ack. Agent = %u", agent); #endif if (gop_finish_helper) gop_finish_helper(agent); chunk_free(msg); break; case MSG_GC_START: chunk_free(msg); gc_start(code); break; case MSG_GC_FINISH: chunk_free(msg); gc_finish(code); break; default: chunk_free(msg); err(false, "Unknown message code %u from controller (ignored)", code); } } else { /* Must be message from router */ switch (code) { case MSG_OPERATION: receive_operation(msg); break; case MSG_OPERAND: receive_operand(msg); break; default: chunk_free(msg); err(false, "Received message with unknown code %u (ignored)", code); } } } } quit_agent(0, NULL); }
/* Client command loop only considers console inputs + controller messages */ void run_client(char *infile_name) { if (!start_cmd(infile_name)) return; while (!cmd_done()) { /* Select among controller port, and connections to routers */ FD_ZERO(&cset); maxcfd = 0; add_cfd(controller_fd); cmd_select(maxcfd+1, &cset, NULL, NULL, NULL); if (cmd_done()) break; int fd; for (fd = 0; fd <= maxcfd; fd++) { if (!FD_ISSET(fd, &cset)) continue; bool eof; chunk_ptr msg = chunk_read(fd, &eof); if (eof) { /* Unexpected EOF */ if (fd == controller_fd) { err(true, "Unexpected EOF from controller (fatal)"); } else { err(false, "Unexpected EOF from unexpected source. fd %d (ignored)", fd); } close(fd); continue; } if (msg == NULL) { err(false, "Could not read chunk from fd %d (ignored)", fd); continue; } word_t h = chunk_get_word(msg, 0); unsigned code = msg_get_header_code(h); if (fd == controller_fd) { /* Message from controller */ switch(code) { case MSG_DO_FLUSH: chunk_free(msg); #if RPT >= 5 report(5, "Received flush message from controller"); #endif if (flush_helper) { flush_helper(); } break; case MSG_STAT: #if RPT >= 5 report(5, "Received summary statistics from controller"); #endif if (stat_helper) { /* Get a copy of the byte usage from mem. allocator */ stat_helper(msg); } chunk_free(msg); /* Client can proceed with next command */ unblock_console(); break; case MSG_KILL: chunk_free(msg); #if RPT >= 1 report(1, "Received kill message from controller"); #endif finish_cmd(); break; case MSG_GC_START: chunk_free(msg); gc_start(code); break; case MSG_GC_FINISH: chunk_free(msg); gc_finish(code); break; default: chunk_free(msg); err(false, "Unknown message code %u from controller (ignored)", code); } } else { err(false, "Received message from unknown source. fd %d (ignored)", fd); close(fd); continue; } } } }