X-Git-Url: https://git.sesse.net/?p=cubemap;a=blobdiff_plain;f=server.cpp;h=aed8779a25a3807c02347f2c19063b581c016b63;hp=5c55636668eca819141f44099461ae419c51d997;hb=733fa6455f39af91b105b82968f88a0165a66f08;hpb=019b96a9cc6fa2902690e98a2aa033517efef3ed diff --git a/server.cpp b/server.cpp index 5c55636..aed8779 100644 --- a/server.cpp +++ b/server.cpp @@ -9,12 +9,14 @@ #include #include #include +#include #include #include #include #include #include +#include "markpool.h" #include "metacube.h" #include "server.h" #include "mutexlock.h" @@ -25,6 +27,7 @@ using namespace std; Client::Client(int sock) : sock(sock), + fwmark(0), connect_time(time(NULL)), state(Client::READING_REQUEST), stream(NULL), @@ -63,6 +66,16 @@ Client::Client(const ClientProto &serialized, Stream *stream) header_or_error_bytes_sent(serialized.header_or_error_bytes_sent()), bytes_sent(serialized.bytes_sent()) { + if (stream->mark_pool != NULL) { + fwmark = stream->mark_pool->get_mark(); + } else { + fwmark = 0; // No mark. + } + if (setsockopt(sock, SOL_SOCKET, SO_MARK, &fwmark, sizeof(fwmark)) == -1) { + if (fwmark != 0) { + perror("setsockopt(SO_MARK)"); + } + } } ClientProto Client::serialize() const @@ -93,7 +106,8 @@ ClientStats Client::get_stats() const Stream::Stream(const string &stream_id) : stream_id(stream_id), data(new char[BACKLOG_SIZE]), - data_size(0) + data_size(0), + mark_pool(NULL) { memset(data, 0, BACKLOG_SIZE); } @@ -107,7 +121,8 @@ Stream::Stream(const StreamProto &serialized) : stream_id(serialized.stream_id()), header(serialized.header()), data(new char[BACKLOG_SIZE]), - data_size(serialized.data_size()) + data_size(serialized.data_size()), + mark_pool(NULL) { assert(serialized.data().size() == BACKLOG_SIZE); memcpy(data, serialized.data().data(), BACKLOG_SIZE); @@ -180,6 +195,7 @@ void Server::stop() should_stop = true; } + pthread_kill(worker_thread, SIGHUP); if (pthread_join(worker_thread, NULL) == -1) { perror("pthread_join"); exit(1); @@ -211,6 +227,9 @@ void Server::do_work() for ( ;; ) { int nfds = epoll_wait(epoll_fd, events, EPOLL_MAX_EVENTS, EPOLL_TIMEOUT_MS); if (nfds == -1 && errno == EINTR) { + if (should_stop) { + return; + } continue; } if (nfds == -1) { @@ -220,10 +239,6 @@ void Server::do_work() MutexLock lock(&mutex); // We release the mutex between iterations. - if (should_stop) { - return; - } - process_queued_data(); for (int i = 0; i < nfds; ++i) { @@ -248,6 +263,10 @@ void Server::do_work() process_client(to_process[i]); } } + + if (should_stop) { + return; + } } } @@ -353,6 +372,13 @@ void Server::set_header(const string &stream_id, const string &header) } } } + +void Server::set_mark_pool(const std::string &stream_id, MarkPool *mark_pool) +{ + MutexLock lock(&mutex); + assert(clients.empty()); + find_stream(stream_id)->mark_pool = mark_pool; +} void Server::add_data_deferred(const string &stream_id, const char *data, size_t bytes) { @@ -577,6 +603,16 @@ int Server::parse_request(Client *client) client->stream_id = request_tokens[1]; client->stream = find_stream(client->stream_id); + if (client->stream->mark_pool != NULL) { + client->fwmark = client->stream->mark_pool->get_mark(); + } else { + client->fwmark = 0; // No mark. + } + if (setsockopt(client->sock, SOL_SOCKET, SO_MARK, &client->fwmark, sizeof(client->fwmark)) == -1) { + if (client->fwmark != 0) { + perror("setsockopt(SO_MARK)"); + } + } client->request.clear(); return 200; // OK! @@ -639,8 +675,12 @@ void Server::close_client(Client *client) if (client->stream != NULL) { delete_from(&client->stream->sleeping_clients, client); delete_from(&client->stream->to_process, client); + if (client->stream->mark_pool != NULL) { + int fwmark = client->fwmark; + client->stream->mark_pool->release_mark(fwmark); + } } - + // Bye-bye! int ret; do {