fix: Safely remove decode tasks

This commit is contained in:
dreamsourcelabTAI 2022-04-29 15:37:22 +08:00
parent 5fe37c7d62
commit c3ab42fcf5
6 changed files with 72 additions and 50 deletions

View File

@ -388,7 +388,7 @@ void DecoderStack::stop_decode_work()
{
//set the flag to exit from task thread
if (_stask_stauts){
_stask_stauts->m_bStop = true;
_stask_stauts->_bStop = true;
}
_decode_state = Stopped;
}
@ -407,10 +407,11 @@ void DecoderStack::do_decode_work()
{
//set the flag to exit from task thread
if (_stask_stauts){
_stask_stauts->m_bStop = true;
_stask_stauts->_bStop = true;
}
_stask_stauts = new decode_task_status();
_stask_stauts->m_bStop = false;
_stask_stauts->_bStop = false;
_stask_stauts->_decoder = this;
_decoder_status->clear(); //clear old items
pv::view::LogicSignal *logic_signal = NULL;
@ -514,7 +515,7 @@ void DecoderStack::decode_data(const uint64_t decode_start, const uint64_t decod
qDebug()<<"decode data index have been end:"<<i;
}
while(i < decode_end && !_no_memory && !status->m_bStop)
while(i < decode_end && !_no_memory && !status->_bStop)
{
std::vector<const uint8_t *> chunk;
std::vector<uint8_t> chunk_const;
@ -637,8 +638,11 @@ void DecoderStack::execute_decode_stack()
srd_session_metadata_set(session, SRD_CONF_SAMPLERATE,
g_variant_new_uint64((uint64_t)_samplerate));
srd_pd_output_callback_add(session, SRD_OUTPUT_ANN,
DecoderStack::annotation_callback, this);
srd_pd_output_callback_add(
session,
SRD_OUTPUT_ANN,
DecoderStack::annotation_callback,
_stask_stauts);
char *error = NULL;
if (srd_session_start(session, &error) == SRD_OK)
@ -668,14 +672,25 @@ uint64_t DecoderStack::sample_rate()
}
//the decode callback, annotation object will be create
void DecoderStack::annotation_callback(srd_proto_data *pdata, void *decoder)
void DecoderStack::annotation_callback(srd_proto_data *pdata, void *self)
{
assert(pdata);
assert(decoder);
assert(self);
DecoderStack *const d = (DecoderStack*)decoder;
struct decode_task_status *st = (decode_task_status*)self;
DecoderStack *const d = st->_decoder;
assert(d);
if (st->_bStop){
qDebug()<<"decode task was stoped.";
return;
}
if (d->_decoder_status == NULL){
qDebug()<<"decode task was deleted.";
assert(false);
}
if (d->_no_memory) {
return;
}

View File

@ -35,11 +35,6 @@
#include "decode/decoderstatus.h"
struct decode_task_status
{
volatile bool m_bStop;
};
namespace DecoderStackTest {
class TwoDecoderStack;
}
@ -63,6 +58,13 @@ class RowData;
}
class Logic;
class DecoderStack;
struct decode_task_status
{
volatile bool _bStop;
DecoderStack *_decoder;
};
//a torotocol have a DecoderStack, destroy by DecodeTrace
class DecoderStack : public QObject, public SignalData
@ -163,7 +165,7 @@ public:
private:
void decode_data(const uint64_t decode_start, const uint64_t decode_end, srd_session *const session);
void execute_decode_stack();
static void annotation_callback(srd_proto_data *pdata, void *decoder);
static void annotation_callback(srd_proto_data *pdata, void *self);
void do_decode_work();
signals:

View File

@ -113,7 +113,12 @@ void LogicSnapshot::capture_ended()
uint64_t index0 = block_index / RootScale;
uint64_t index1 = block_index % RootScale;
int order = 0;
for(auto& iter:_ch_data) {
if (iter[index0].lbp[index1] == NULL){
assert(false);
}
const uint64_t *end_ptr = (uint64_t *)iter[index0].lbp[index1] + (LeafBlockSamples / Scale);
uint64_t *ptr = (uint64_t *)iter[index0].lbp[index1] + block_offset;
while (ptr < end_ptr)

View File

@ -126,13 +126,6 @@ DevInst* SigSession::get_device()
return _dev_inst;
}
void SigSession::deselect_device()
{
RELEASE_ARRAY(_decode_traces);
RELEASE_ARRAY(_group_traces);
_dev_inst = NULL;
}
/*
when be called, it will call 4DSL lib sr_session_new, and create a session struct in the lib
*/
@ -142,20 +135,18 @@ void SigSession::set_device(DevInst *dev_inst)
assert(dev_inst);
if (_dev_inst){
_dev_inst->dev_inst();
}
clear_all_decoder(false);
RELEASE_ARRAY(_group_traces);
if (_dev_inst) {
sr_session_datafeed_callback_remove_all();
_dev_inst->release();
_dev_inst = NULL;
}
_dev_inst = dev_inst;
RELEASE_ARRAY(_decode_traces);
RELEASE_ARRAY(_group_traces);
if (_dev_inst) {
try {
_dev_inst->use(this);
@ -180,7 +171,17 @@ void SigSession::set_file(QString name)
{
// Deslect the old device, because file type detection in File::create
// destorys the old session inside libsigrok.
deselect_device();
clear_all_decoder(false);
RELEASE_ARRAY(_group_traces);
//File::create(name) will get resource, so try to release old file before
if (_dev_inst) {
sr_session_datafeed_callback_remove_all();
_dev_inst->release();
_dev_inst = NULL;
}
try {
set_device(device::File::create(name));
@ -196,6 +197,7 @@ void SigSession::close_file(DevInst *dev_inst)
assert(_device_manager);
try {
clear_all_decoder();
dev_inst->device_updated();
set_repeating(false);
stop_capture();
@ -500,13 +502,6 @@ void SigSession::sample_thread_proc(DevInst *dev_inst)
}
void SigSession::stop_capture()
{
do_stop_capture();
int dex = 0;
clear_all_decode_task(dex);
}
void SigSession::do_stop_capture()
{
data_unlock();
@ -689,7 +684,7 @@ void SigSession::init_signals()
// Clear the decode traces
RELEASE_ARRAY(_decode_traces);
clear_all_decoder();
// Detect what data types we will receive
if(_dev_inst) {
@ -1786,7 +1781,7 @@ void SigSession::set_stop_scale(float scale)
_bClose = true;
do_stop_capture(); //stop capture
stop_capture(); //stop capture
clear_all_decoder(); //clear all decode task, and stop decode thread
@ -1841,7 +1836,7 @@ void SigSession::set_stop_scale(float scale)
trace->decoder()->stop_decode_work();
}
void SigSession::clear_all_decoder()
void SigSession::clear_all_decoder(bool bUpdateView)
{
//create the wait task deque
int dex = -1;
@ -1868,8 +1863,9 @@ void SigSession::set_stop_scale(float scale)
_decode_thread.join();
}
if (!is_closed())
signals_changed();
if (!is_closed() && bUpdateView){
signals_changed();
}
}
void SigSession::clear_all_decode_task(int &runningDex)

View File

@ -134,7 +134,7 @@ public:
* Sets device instance that will be used in the next capture session.
*/
void set_device(DevInst *dev_inst);
void deselect_device();
void set_file(QString name);
void close_file(DevInst *dev_inst);
void set_default_device();
@ -232,7 +232,7 @@ public:
sr_dev_inst* get_dev_inst_c();
void Open();
void Close();
void clear_all_decoder();
void clear_all_decoder(bool bUpdateView = true);
inline bool is_closed(){
return _bClose;
@ -294,7 +294,6 @@ private:
view::DecodeTrace* get_top_decode_task();
void capture_init();
void do_stop_capture();
void data_lock();
void data_unlock();
void nodata_timeout();

View File

@ -740,7 +740,12 @@ void View::signals_changed()
const double height = (_time_viewport->height()
- 2 * actualMargin * label_size) * 1.0 / total_rows;
if (_session->get_device()->dev_inst()->mode == LOGIC) {
auto dev = _session->get_device();
assert(dev);
auto ins = dev->dev_inst();
assert(ins);
if (ins->mode == LOGIC) {
GVariant* gvar = _session->get_device()->get_config(NULL, NULL, SR_CONF_MAX_HEIGHT_VALUE);
if (gvar != NULL) {
max_height = (g_variant_get_byte(gvar) + 1) * MaxHeightUnit;