Пример #1
0
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;
}
Пример #2
0
void McProtocolSerializer::readData(std::unique_ptr<folly::IOBuf>&& data) {
  auto bytes = data->coalesce();
  mc_parser_parse(&parser_, bytes.begin(), bytes.size());
}