X-Git-Url: https://git.sesse.net/?p=cubemap;a=blobdiff_plain;f=server.cpp;h=946dc5d1df12d0c5b9c3d88058c0b5dad68c5a8d;hp=01ed0ff041697ce1894c16652b374c66881e92f3;hb=2fbbdf3c4a4ffd2d90c102a37c7a02b5b6f80216;hpb=1dfa45f9af3f885a50d2bef384ea89b0a4cf17c5 diff --git a/server.cpp b/server.cpp index 01ed0ff..946dc5d 100644 --- a/server.cpp +++ b/server.cpp @@ -217,9 +217,15 @@ void Server::add_client(int sock) assert(ret.second == true); // Should not already exist. Client *client_ptr = &ret.first->second; - // Connection timestamps must be nondecreasing. - assert(clients_ordered_by_connect_time.empty() || - !is_earlier(client_ptr->connect_time, clients_ordered_by_connect_time.back().first)); + // Connection timestamps must be nondecreasing. I can't find any guarantee + // that even the monotonic clock can't go backwards by a small amount + // (think switching between CPUs with non-synchronized TSCs), so if + // this actually should happen, we hack around it by fudging + // connect_time. + if (!clients_ordered_by_connect_time.empty() && + is_earlier(client_ptr->connect_time, clients_ordered_by_connect_time.back().first)) { + client_ptr->connect_time = clients_ordered_by_connect_time.back().first; + } clients_ordered_by_connect_time.push(make_pair(client_ptr->connect_time, sock)); // Start listening on data from this socket. @@ -311,6 +317,13 @@ void Server::set_backlog_size(int stream_index, size_t new_size) assert(stream_index >= 0 && stream_index < ssize_t(streams.size())); streams[stream_index]->set_backlog_size(new_size); } + +void Server::set_prebuffering_bytes(int stream_index, size_t new_amount) +{ + MutexLock lock(&mutex); + assert(stream_index >= 0 && stream_index < ssize_t(streams.size())); + streams[stream_index]->prebuffering_bytes = new_amount; +} void Server::set_encoding(int stream_index, Stream::Encoding encoding) { @@ -325,6 +338,7 @@ void Server::set_header(int stream_index, const string &http_header, const strin assert(stream_index >= 0 && stream_index < ssize_t(streams.size())); streams[stream_index]->http_header = http_header; streams[stream_index]->stream_header = stream_header; + // FIXME: We should reset last_suitable_starting_point at this point. } void Server::set_pacing_rate(int stream_index, uint32_t pacing_rate) @@ -465,14 +479,15 @@ sending_header_or_error_again: } case Client::WAITING_FOR_KEYFRAME: { Stream *stream = client->stream; - if (ssize_t(client->stream_pos) > stream->last_suitable_starting_point) { + if (stream->suitable_starting_points.empty() || + client->stream_pos > stream->suitable_starting_points.back()) { // We haven't received a keyframe since this stream started waiting, // so keep on waiting for one. // This is postcondition #3. stream->put_client_to_sleep(client); return; } - client->stream_pos = stream->last_suitable_starting_point; + client->stream_pos = stream->suitable_starting_points.back(); client->state = Client::PREBUFFERING; // Fall through. } @@ -482,6 +497,7 @@ sending_header_or_error_again: assert(bytes_to_send <= stream->backlog_size); if (bytes_to_send < stream->prebuffering_bytes) { // We don't have enough bytes buffered to start this client yet. + // This is postcondition #3. stream->put_client_to_sleep(client); return; } @@ -565,6 +581,18 @@ int Server::parse_request(Client *client) return 400; // Bad request (empty). } + // Parse the headers, for logging purposes. + // TODO: Case-insensitivity. + multimap headers = extract_headers(lines, client->remote_addr); + multimap::const_iterator referer_it = headers.find("Referer"); + if (referer_it != headers.end()) { + client->referer = referer_it->second; + } + multimap::const_iterator user_agent_it = headers.find("User-Agent"); + if (user_agent_it != headers.end()) { + client->user_agent = user_agent_it->second; + } + vector request_tokens = split_tokens(lines[0]); if (request_tokens.size() < 2) { return 400; // Bad request (empty). @@ -592,6 +620,7 @@ int Server::parse_request(Client *client) } client->url = request_tokens[1]; + client->stream = stream; if (setsockopt(client->sock, SOL_SOCKET, SO_MAX_PACING_RATE, &client->stream->pacing_rate, sizeof(client->stream->pacing_rate)) == -1) { if (client->stream->pacing_rate != ~0U) {