static mm_value_t mc_reader_routine(struct mm_work *work) { ENTER(); struct mm_net_socket *sock = mm_net_reader_socket(work); struct mc_state *state = containerof(sock, struct mc_state, sock.sock); // Try to get some input w/o blocking. mm_net_set_read_timeout(&state->sock.sock, 0); ssize_t n = mm_netbuf_fill(&state->sock, 1); mm_net_set_read_timeout(&state->sock.sock, MC_READ_TIMEOUT); retry: // Get out of here if there is no more input available. if (n <= 0) { if (n == 0 || (errno != EAGAIN && errno != ETIMEDOUT)) state->error = true; // If the socket is closed queue a quit command. if (state->error && !mm_net_is_reader_shutdown(sock)) { struct mc_command *command = mc_command_create(state); command->type = &mc_command_ascii_quit; mc_process_command(state, command); } goto leave; } // Initialize the parser. struct mm_buffer_reader safepoint; mm_netbuf_capture_read_pos(&state->sock, &safepoint); mc_protocol_t protocol = mc_getprotocol(state); state->command = NULL; // Try to parse the received input. bool rc; parse: if (protocol == MC_PROTOCOL_BINARY) rc = mc_binary_parse(state); else rc = mc_parser_parse(state); if (!rc) { if (state->command != NULL) { mc_command_destroy(state->command); state->command = NULL; } if (state->trash) { mm_netbuf_reset(&state->sock); mm_warning(0, "disconnect an odd client"); goto leave; } // The input is incomplete, try to get some more. mm_netbuf_restore_read_pos(&state->sock, &safepoint); n = mm_netbuf_fill(&state->sock, 1); goto retry; } // Process the parsed command. mc_process_command(state, state->command); // If there is more input in the buffer then try to parse // the next command. if (!mm_netbuf_empty(&state->sock)) { state->command = NULL; // Update the safe consumed input position. mm_netbuf_capture_read_pos(&state->sock, &safepoint); goto parse; } // Transmit buffered results and compact the output buffer storage. mm_netbuf_flush(&state->sock); mm_netbuf_compact_write_buf(&state->sock); // Compact the input buffer storage. mm_netbuf_compact_read_buf(&state->sock); leave: LEAVE(); return 0; }
void McProtocolSerializer::readData(std::unique_ptr<folly::IOBuf>&& data) { auto bytes = data->coalesce(); mc_parser_parse(&parser_, bytes.begin(), bytes.size()); }