lf_queue: add range-for support (endless loop with waiting)

This commit is contained in:
Nekotekina 2019-10-12 22:37:52 +03:00
parent 16dd72b3e3
commit 5624b001ae
2 changed files with 66 additions and 9 deletions

View file

@ -401,6 +401,64 @@ public:
return count; return count;
} }
// Iterator that enables direct endless range-for loop: for (auto* ptr : queue) ...
class iterator
{
lf_queue* _this = nullptr;
lf_queue_slice<T> m_data;
public:
constexpr iterator() = default;
explicit iterator(lf_queue* _this)
: _this(_this)
{
m_data = _this->pop_all();
}
bool operator !=(const iterator& rhs) const
{
return _this != rhs._this;
}
T* operator *() const
{
return m_data ? m_data.get() : nullptr;
}
iterator& operator ++()
{
if (m_data)
{
m_data.pop_front();
}
if (!m_data)
{
m_data = _this->pop_all();
if (!m_data)
{
_this->wait();
m_data = _this->pop_all();
}
}
return *this;
}
};
iterator begin()
{
return iterator{this};
}
iterator end()
{
return iterator{};
}
}; };
// Assignable lock-free thread-safe value of any type (memory-inefficient) // Assignable lock-free thread-safe value of any type (memory-inefficient)

View file

@ -180,15 +180,14 @@ struct vdec_context final
{ {
ppu_tid = ppu.id; ppu_tid = ppu.id;
for (auto cmds = in_cmd.pop_all(); thread_ctrl::state() != thread_state::aborting; cmds ? cmds.pop_front() : cmds = in_cmd.pop_all()) // pcmd can be nullptr
for (auto* pcmd : in_cmd)
{ {
if (!cmds) if (thread_ctrl::state() == thread_state::aborting)
{ {
in_cmd.wait(); break;
continue;
} }
else if (std::get_if<vdec_start_seq_t>(pcmd))
if (std::get_if<vdec_start_seq_t>(&*cmds))
{ {
avcodec_flush_buffers(ctx); avcodec_flush_buffers(ctx);
@ -197,7 +196,7 @@ struct vdec_context final
next_dts = 0; next_dts = 0;
cellVdec.trace("Start sequence..."); cellVdec.trace("Start sequence...");
} }
else if (auto* cmd = std::get_if<vdec_cmd>(&*cmds)) else if (auto* cmd = std::get_if<vdec_cmd>(pcmd))
{ {
AVPacket packet{}; AVPacket packet{};
packet.pos = -1; packet.pos = -1;
@ -399,11 +398,11 @@ struct vdec_context final
thread_ctrl::wait_for(1000); thread_ctrl::wait_for(1000);
} }
} }
else if (auto* frc = std::get_if<CellVdecFrameRate>(&*cmds)) else if (auto* frc = std::get_if<CellVdecFrameRate>(pcmd))
{ {
frc_set = *frc; frc_set = *frc;
} }
else else if (std::get_if<vdec_close_t>(pcmd))
{ {
break; break;
} }