From 0232417512ea1cb5cdc0ba2a45b1ac1a6ea434d2 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 28 Jul 2016 20:44:15 +0200 Subject: [PATCH 1/4] Added method to count currently playing tracks in Output classes --- src/output/output.cpp | 4 ++++ src/output/output.h | 1 + 2 files changed, 5 insertions(+) diff --git a/src/output/output.cpp b/src/output/output.cpp index ae7d6ec7..f4258026 100644 --- a/src/output/output.cpp +++ b/src/output/output.cpp @@ -60,6 +60,10 @@ namespace Mist { isBlocking = blocking; myConn.setBlocking(isBlocking); } + + uint32_t Output::currTrackCount() const{ + return buffer.size(); + } void Output::updateMeta(){ //read metadata from page to myMeta variable diff --git a/src/output/output.h b/src/output/output.h index 3cbd0c5c..d7ba6e2e 100644 --- a/src/output/output.h +++ b/src/output/output.h @@ -53,6 +53,7 @@ namespace Mist { void selectDefaultTracks(); bool connectToFile(std::string file); static bool listenMode(){return true;} + uint32_t currTrackCount() const; virtual bool isReadyForPlay(); //virtuals. The optional virtuals have default implementations that do as little as possible. virtual void sendNext() {}//REQUIRED! Others are optional. From 4dc3d22d12b3b22ae4d8435ca8f00b6015d969c7 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 28 Jul 2016 20:41:44 +0200 Subject: [PATCH 2/4] Fixed potential deadlock in buffer when a past crash has happened --- lib/shared_memory.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/shared_memory.cpp b/lib/shared_memory.cpp index 0faf16a2..d0041fd5 100644 --- a/lib/shared_memory.cpp +++ b/lib/shared_memory.cpp @@ -766,6 +766,10 @@ namespace IPC { DEBUG_MSG(DLVL_FAIL, "Creating semaphore failed: %s", strerror(errno)); return; } + if (!mySemaphore.tryWaitOneSecond()){ + WARN_MSG("Force unlocking sharedServer semaphore to prevent deadlock"); + } + mySemaphore.post(); semGuard tmpGuard(&mySemaphore); newPage(); } From 5ffe12aba45b8206b91380cae6dfc123590b19dc Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 28 Jul 2016 20:45:31 +0200 Subject: [PATCH 3/4] Tweaked several debug messages, backported a few Pro edition edits that were missed earlier --- lib/dtscmeta.cpp | 7 ++-- src/input/input.cpp | 6 ++-- src/input/input_dtsc.cpp | 76 ++++++++++++++++++++++++---------------- 3 files changed, 53 insertions(+), 36 deletions(-) diff --git a/lib/dtscmeta.cpp b/lib/dtscmeta.cpp index d1b13ed4..bd403e24 100644 --- a/lib/dtscmeta.cpp +++ b/lib/dtscmeta.cpp @@ -120,7 +120,7 @@ namespace DTSC { while (src.connected()){ if (!toReceive && src.Received().available(8)){ if (src.Received().copy(2) != "DT"){ - INFO_MSG("Invalid DTSC Packet header encountered (%s)", src.Received().copy(4).c_str()); + WARN_MSG("Invalid DTSC Packet header encountered (%s)", src.Received().copy(4).c_str()); break; } toReceive = Bit::btohl(src.Received().copy(8).data() + 4); @@ -131,10 +131,11 @@ namespace DTSC { return; } if(!src.spool()){ - if (sleepCount++ > 60){ + if (sleepCount++ > 50){ + WARN_MSG("Waiting for packet on connection timed out"); return; } - Util::sleep(100); + Util::wait(100); } } } diff --git a/src/input/input.cpp b/src/input/input.cpp index d746eb8b..5fd93f94 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -228,7 +228,7 @@ namespace Mist { snprintf(userPageName, NAME_BUFFER_SIZE, SHM_USERS, streamName.c_str()); nProxy.userClient = IPC::sharedClient(userPageName, PLAY_EX_SIZE, true); - DEBUG_MSG(DLVL_DEVEL, "Input for stream %s started", streamName.c_str()); + INFO_MSG("Input for stream %s started", streamName.c_str()); if (!openStreamSource()){ FAIL_MSG("Unable to connect to source"); @@ -261,7 +261,7 @@ namespace Mist { getNext(); nProxy.userClient.keepAlive(); } - + closeStreamSource(); nProxy.userClient.finish(); @@ -269,7 +269,7 @@ namespace Mist { pullLock.post(); pullLock.close(); pullLock.unlink(); - DEBUG_MSG(DLVL_DEVEL, "Pull input for stream %s closing clean", streamName.c_str()); + INFO_MSG("Stream input %s closing clean", streamName.c_str()); return; } diff --git a/src/input/input_dtsc.cpp b/src/input/input_dtsc.cpp index fbdc439b..e13b0595 100644 --- a/src/input/input_dtsc.cpp +++ b/src/input/input_dtsc.cpp @@ -164,28 +164,28 @@ namespace Mist { if (!needsLock()) { return true; } else { - if (config->getString("input") == "-") { - std::cerr << "Input from stdin not yet supported" << std::endl; - return false; - } - if (!config->getString("streamname").size()){ - if (config->getString("output") == "-") { - std::cerr << "Output to stdout not yet supported" << std::endl; + if (config->getString("input") == "-") { + std::cerr << "Input from stdin not yet supported" << std::endl; return false; } - }else{ - if (config->getString("output") != "-") { - std::cerr << "File output in player mode not supported" << std::endl; + if (!config->getString("streamname").size()) { + if (config->getString("output") == "-") { + std::cerr << "Output to stdout not yet supported" << std::endl; + return false; + } + } else { + if (config->getString("output") != "-") { + std::cerr << "File output in player mode not supported" << std::endl; + return false; + } + } + + //open File + inFile = DTSC::File(config->getString("input")); + if (!inFile) { return false; } } - - //open File - inFile = DTSC::File(config->getString("input")); - if (!inFile) { - return false; - } - } return true; } @@ -199,18 +199,18 @@ namespace Mist { DTSC::File tmp(config->getString("input") + ".dtsh"); if (tmp) { myMeta = tmp.getMeta(); - DEBUG_MSG(DLVL_HIGH,"Meta read in with %lu tracks", myMeta.tracks.size()); + DEBUG_MSG(DLVL_HIGH, "Meta read in with %lu tracks", myMeta.tracks.size()); return true; } if (inFile.getMeta().moreheader < 0 || inFile.getMeta().tracks.size() == 0) { - DEBUG_MSG(DLVL_FAIL,"Missing external header file"); + DEBUG_MSG(DLVL_FAIL, "Missing external header file"); return false; } myMeta = DTSC::Meta(inFile.getMeta()); - DEBUG_MSG(DLVL_DEVEL,"Meta read in with %lu tracks", myMeta.tracks.size()); + DEBUG_MSG(DLVL_DEVEL, "Meta read in with %lu tracks", myMeta.tracks.size()); return true; } - + void inputDTSC::getNext(bool smart) { if (!needsLock()){ thisPacket.reInit(srcConn); @@ -232,7 +232,7 @@ namespace Mist { } for (std::set::iterator it = newTracks.begin(); it != newTracks.end(); it++){ - INFO_MSG("Adding track %d to internal metadata", *it); + INFO_MSG("Reset: adding track %d", *it); myMeta.tracks[*it] = newMeta.tracks[*it]; continueNegotiate(*it, true); } @@ -246,12 +246,12 @@ namespace Mist { } for(std::set::iterator it = deletedTracks.begin(); it != deletedTracks.end(); it++){ - INFO_MSG("Deleting track %d from internal metadata", *it); + INFO_MSG("Reset: deleting track %d", *it); myMeta.tracks.erase(*it); } //Read next packet before returning - thisPacket.reInit(srcConn); + return getNext(smart); }else{ myMeta = DTSC::Meta(); } @@ -259,14 +259,30 @@ namespace Mist { //Read next packet before returning thisPacket.reInit(srcConn); } + }else if (thisPacket.getVersion() == DTSC::DTSC_HEAD){ + DTSC::Meta newMeta; + newMeta.reinit(thisPacket); + std::set newTracks; + for (std::map::iterator it = newMeta.tracks.begin(); it != newMeta.tracks.end(); it++){ + if (!myMeta.tracks.count(it->first)){ + newTracks.insert(it->first); + } + } + + for (std::set::iterator it = newTracks.begin(); it != newTracks.end(); it++){ + INFO_MSG("New header: adding track %d (%s)", *it, newMeta.tracks[*it].type.c_str()); + myMeta.tracks[*it] = newMeta.tracks[*it]; + continueNegotiate(*it, true); + } + return getNext(smart); } }else{ - if (smart){ - inFile.seekNext(); - }else{ - inFile.parseNext(); - } - thisPacket = inFile.getPacket(); + if (smart) { + inFile.seekNext(); + } else { + inFile.parseNext(); + } + thisPacket = inFile.getPacket(); } } From 2bdafc245ddee9a7475ea6a1dc0e17b546a68839 Mon Sep 17 00:00:00 2001 From: Thulinma Date: Thu, 28 Jul 2016 20:42:51 +0200 Subject: [PATCH 4/4] Fixed segmentation fault in buffer process for fast reconnects of sources --- src/input/input_buffer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/input/input_buffer.cpp b/src/input/input_buffer.cpp index 084eddb2..e16b7b0d 100644 --- a/src/input/input_buffer.cpp +++ b/src/input/input_buffer.cpp @@ -627,6 +627,7 @@ namespace Mist { //Store a reference for easier access std::map & locations = bufferLocations[tNum]; char * mappedPointer = nProxy.metaPages[tNum].mapped; + if (!mappedPointer){return;} //First detect all entries on metaPage for (int i = 0; i < 8192; i += 8) {