| 95 | } |
| 96 | |
| 97 | std::vector<RecordedTrace> Tracer::stopRecording(size_t recordingIdentifier) { |
| 98 | std::lock_guard<std::mutex> lock(_mutex); |
| 99 | |
| 100 | auto it = std::find(_recorders.begin(), _recorders.end(), recordingIdentifier); |
| 101 | if (it == _recorders.end()) { |
| 102 | return {}; |
| 103 | } |
| 104 | |
| 105 | _recorders.erase(it); |
| 106 | |
| 107 | // Simple case, we only have one recorder we can return all the recorded traces |
| 108 | if (_recorders.empty()) { |
| 109 | _recording = false; |
| 110 | return std::move(_pendingTraces); |
| 111 | } |
| 112 | |
| 113 | // We still have one active recorder. We collect the traces that ocurreded with or after |
| 114 | // this identifier |
| 115 | |
| 116 | std::vector<RecordedTrace> outTraces; |
| 117 | |
| 118 | for (const auto& trace : _pendingTraces) { |
| 119 | if (trace.recordingSequence >= recordingIdentifier) { |
| 120 | outTraces.emplace_back(trace); |
| 121 | } |
| 122 | } |
| 123 | |
| 124 | auto lowestRecordingIdentifier = *_recorders.begin(); |
| 125 | if (lowestRecordingIdentifier > recordingIdentifier) { |
| 126 | // If the next lowest recording identifier is above the ending identifier, |
| 127 | // we might have dangling traces to remove. |
| 128 | // Remove all the traces that occured before the new lowest recording identifier. |
| 129 | auto newStartIt = _pendingTraces.begin(); |
| 130 | while (newStartIt != _pendingTraces.end() && newStartIt->recordingSequence < lowestRecordingIdentifier) { |
| 131 | newStartIt++; |
| 132 | } |
| 133 | _pendingTraces.erase(_pendingTraces.begin(), newStartIt); |
| 134 | } |
| 135 | |
| 136 | return outTraces; |
| 137 | } |
| 138 | |
| 139 | } // namespace Valdi |