X-Git-Url: https://git.sesse.net/?p=cubemap;a=blobdiff_plain;f=stream.cpp;h=b7a92c2293832e7d77c3b0c8b4c20e604b195a44;hp=4840b06b070b84eaf20e70053eff4c38efb86240;hb=d19e6c3ed8e85f5a39793903114d4de38b5a1609;hpb=bfc1a54cf84bb1784c14bd4f5acbb500460e35b5 diff --git a/stream.cpp b/stream.cpp index 4840b06..b7a92c2 100644 --- a/stream.cpp +++ b/stream.cpp @@ -11,6 +11,7 @@ #include "log.h" #include "metacube2.h" +#include "mutexlock.h" #include "state.pb.h" #include "stream.h" #include "util.h" @@ -30,6 +31,8 @@ Stream::Stream(const string &url, size_t backlog_size, Encoding encoding) if (data_fd == -1) { exit(1); } + + pthread_mutex_init(&queued_data_mutex, NULL); } Stream::~Stream() @@ -73,6 +76,8 @@ Stream::Stream(const StreamProto &serialized, int data_fd) } else { last_suitable_starting_point = bytes_received; } + + pthread_mutex_init(&queued_data_mutex, NULL); } StreamProto Stream::serialize() @@ -212,6 +217,7 @@ void Stream::add_data_raw(const vector &orig_data) void Stream::add_data_deferred(const char *data, size_t bytes, StreamStartSuitability suitable_for_stream_start) { + MutexLock lock(&queued_data_mutex); assert(suitable_for_stream_start == SUITABLE_FOR_STREAM_START || suitable_for_stream_start == NOT_SUITABLE_FOR_STREAM_START); if (suitable_for_stream_start == SUITABLE_FOR_STREAM_START) { @@ -252,27 +258,36 @@ void Stream::add_data_deferred(const char *data, size_t bytes, StreamStartSuitab void Stream::process_queued_data() { - if (queued_data.empty()) { - return; + std::vector queued_data_copy; + int queued_data_last_starting_point_copy = -1; + + // Hold the lock for as short as possible, since add_data_raw() can possibly + // write to disk, which might disturb the input thread. + { + MutexLock lock(&queued_data_mutex); + if (queued_data.empty()) { + return; + } + + swap(queued_data, queued_data_copy); + swap(queued_data_last_starting_point, queued_data_last_starting_point_copy); } // Update the last suitable starting point for the stream, // if the queued data contains such a starting point. - assert(queued_data_last_starting_point < ssize_t(queued_data.size())); - if (queued_data_last_starting_point >= 0) { + assert(queued_data_last_starting_point_copy < ssize_t(queued_data_copy.size())); + if (queued_data_last_starting_point_copy >= 0) { last_suitable_starting_point = bytes_received; - for (int i = 0; i < queued_data_last_starting_point; ++i) { - last_suitable_starting_point += queued_data[i].iov_len; + for (int i = 0; i < queued_data_last_starting_point_copy; ++i) { + last_suitable_starting_point += queued_data_copy[i].iov_len; } } - add_data_raw(queued_data); - for (size_t i = 0; i < queued_data.size(); ++i) { - char *data = reinterpret_cast(queued_data[i].iov_base); + add_data_raw(queued_data_copy); + for (size_t i = 0; i < queued_data_copy.size(); ++i) { + char *data = reinterpret_cast(queued_data_copy[i].iov_base); delete[] data; } - queued_data.clear(); - queued_data_last_starting_point = -1; // We have more data, so wake up all clients. if (to_process.empty()) {