From 8e10e1f98115c96c841cdc6ef5599beb0b6865b1 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sat, 6 Apr 2013 19:02:43 +0200 Subject: [PATCH] Make Server stoppable. --- cubemap.cpp | 5 +++++ server.cpp | 32 +++++++++++++++++++++++++++----- server.h | 10 ++++++++++ 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/cubemap.cpp b/cubemap.cpp index 4ee5d6f..d0a3ac4 100644 --- a/cubemap.cpp +++ b/cubemap.cpp @@ -112,4 +112,9 @@ int main(int argc, char **argv) Input input(STREAM_ID); input.run(STREAM_URL); + + for (int i = 0; i < NUM_SERVERS; ++i) { + servers[i].stop(); + } + delete[] servers; } diff --git a/server.cpp b/server.cpp index 08f2afd..f5c117b 100644 --- a/server.cpp +++ b/server.cpp @@ -34,8 +34,26 @@ Server::Server() void Server::run() { - pthread_t thread; - pthread_create(&thread, NULL, Server::do_work_thunk, this); + should_stop = false; + + // Joinable is already the default, but it's good to be certain. + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + pthread_create(&worker_thread, &attr, Server::do_work_thunk, this); +} + +void Server::stop() +{ + { + MutexLock lock(&mutex); + should_stop = true; + } + + if (pthread_join(worker_thread, NULL) == -1) { + perror("pthread_join"); + exit(1); + } } void *Server::do_work_thunk(void *arg) @@ -49,13 +67,17 @@ void Server::do_work() { for ( ;; ) { int nfds = epoll_wait(epoll_fd, events, EPOLL_MAX_EVENTS, EPOLL_TIMEOUT_MS); - - MutexLock lock(&mutex); // We release the mutex between iterations. if (nfds == -1) { perror("epoll_wait"); exit(1); } - + + MutexLock lock(&mutex); // We release the mutex between iterations. + + if (should_stop) { + return; + } + for (int i = 0; i < nfds; ++i) { int fd = events[i].data.fd; assert(clients.count(fd) != 0); diff --git a/server.h b/server.h index dea24d8..0f93b7f 100644 --- a/server.h +++ b/server.h @@ -57,14 +57,24 @@ public: // Start a new thread that handles clients. void run(); + + // Stop the thread. + void stop(); + void add_client(int sock); void add_stream(const std::string &stream_id); void set_header(const std::string &stream_id, const std::string &header); void add_data(const std::string &stream_id, const char *data, size_t bytes); private: + pthread_t worker_thread; + + // All variables below this line are protected by the mutex. pthread_mutex_t mutex; + // If the thread should stop or not. + bool should_stop; + // Map from stream ID to stream. std::map streams; -- 2.39.2