From: Steinar H. Gunderson Date: Sun, 7 Apr 2013 19:06:16 +0000 (+0200) Subject: Stop doing find_stream() every time we send out data; it takes some CPU. X-Git-Tag: 1.0.0~183 X-Git-Url: https://git.sesse.net/?p=cubemap;a=commitdiff_plain;h=a0ad2d9d955fcb5f0aa3cf4f89999c34e8408124;ds=sidebyside Stop doing find_stream() every time we send out data; it takes some CPU. --- diff --git a/server.cpp b/server.cpp index c8d6889..855e21c 100644 --- a/server.cpp +++ b/server.cpp @@ -26,17 +26,19 @@ using namespace std; Client::Client(int sock) : sock(sock), state(Client::READING_REQUEST), + stream(NULL), header_or_error_bytes_sent(0), bytes_sent(0) { request.reserve(1024); } -Client::Client(const ClientProto &serialized) +Client::Client(const ClientProto &serialized, Stream *stream) : sock(serialized.sock()), state(State(serialized.state())), request(serialized.request()), stream_id(serialized.stream_id()), + stream(stream), header_or_error(serialized.header_or_error()), header_or_error_bytes_sent(serialized.header_or_error_bytes_sent()), bytes_sent(serialized.bytes_sent()) @@ -211,7 +213,8 @@ void Server::add_client(int sock) void Server::add_client_from_serialized(const ClientProto &client) { MutexLock lock(&mutex); - clients.insert(make_pair(client.sock(), Client(client))); + Stream *stream = find_stream(client.stream_id()); + clients.insert(make_pair(client.sock(), Client(client, stream))); // Start listening on data from this socket. epoll_event ev; @@ -398,20 +401,20 @@ sending_header_or_error_again: // but we'll start sending immediately as we get data. // This is postcondition #3. client->state = Client::SENDING_DATA; - client->bytes_sent = find_stream(client->stream_id)->data_size; + client->bytes_sent = client->stream->data_size; sleeping_clients.push_back(client); return; } case Client::SENDING_DATA: { // See if there's some data we've lost. Ideally, we should drop to a block boundary, // but resync will be the mux's problem. - const Stream &stream = *find_stream(client->stream_id); - size_t bytes_to_send = stream.data_size - client->bytes_sent; + const Stream *stream = client->stream; + size_t bytes_to_send = stream->data_size - client->bytes_sent; if (bytes_to_send > BACKLOG_SIZE) { fprintf(stderr, "WARNING: fd %d lost %lld bytes, maybe too slow connection\n", client->sock, (long long int)(bytes_to_send - BACKLOG_SIZE)); - client->bytes_sent = find_stream(client->stream_id)->data_size - BACKLOG_SIZE; + client->bytes_sent = stream->data_size - BACKLOG_SIZE; bytes_to_send = BACKLOG_SIZE; } @@ -421,10 +424,10 @@ sending_header_or_error_again: size_t bytes_first_part = BACKLOG_SIZE - (client->bytes_sent % BACKLOG_SIZE); iovec iov[2]; - iov[0].iov_base = const_cast(stream.data + (client->bytes_sent % BACKLOG_SIZE)); + iov[0].iov_base = const_cast(stream->data + (client->bytes_sent % BACKLOG_SIZE)); iov[0].iov_len = bytes_first_part; - iov[1].iov_base = const_cast(stream.data); + iov[1].iov_base = const_cast(stream->data); iov[1].iov_len = bytes_to_send - bytes_first_part; do { @@ -433,7 +436,7 @@ sending_header_or_error_again: } else { do { ret = write(client->sock, - stream.data + (client->bytes_sent % BACKLOG_SIZE), + stream->data + (client->bytes_sent % BACKLOG_SIZE), bytes_to_send); } while (ret == -1 && errno == EINTR); } @@ -451,7 +454,7 @@ sending_header_or_error_again: } client->bytes_sent += ret; - if (client->bytes_sent == stream.data_size) { + if (client->bytes_sent == stream->data_size) { // We don't have any more data for this client, so put it to sleep. // This is postcondition #3. put_client_to_sleep(client); @@ -485,6 +488,7 @@ int Server::parse_request(Client *client) } client->stream_id = request_tokens[1]; + client->stream = streams[client->stream_id]; client->request.clear(); return 200; // OK! diff --git a/server.h b/server.h index 24e2fcb..fd309f4 100644 --- a/server.h +++ b/server.h @@ -15,6 +15,7 @@ class ClientProto; class CubemapStateProto; +class Stream; class StreamProto; struct Client { @@ -22,7 +23,7 @@ struct Client { Client(int sock); // Serialization/deserialization. - Client(const ClientProto &serialized); + Client(const ClientProto &serialized, Stream *stream); ClientProto serialize() const; // The file descriptor associated with this socket. @@ -38,6 +39,7 @@ struct Client { // What stream we're connecting to; parsed from . // Not relevant for READING_REQUEST. std::string stream_id; + Stream *stream; // The header we want to send. This is nominally a copy of Stream::header, // but since that might change on reconnects etc., we keep a local copy here.