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 //set the flag to exit from task thread
if (_stask_stauts){ if (_stask_stauts){
_stask_stauts->m_bStop = true; _stask_stauts->_bStop = true;
} }
_decode_state = Stopped; _decode_state = Stopped;
} }
@ -407,10 +407,11 @@ void DecoderStack::do_decode_work()
{ {
//set the flag to exit from task thread //set the flag to exit from task thread
if (_stask_stauts){ if (_stask_stauts){
_stask_stauts->m_bStop = true; _stask_stauts->_bStop = true;
} }
_stask_stauts = new decode_task_status(); _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 _decoder_status->clear(); //clear old items
pv::view::LogicSignal *logic_signal = NULL; 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; 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<const uint8_t *> chunk;
std::vector<uint8_t> chunk_const; std::vector<uint8_t> chunk_const;
@ -637,8 +638,11 @@ void DecoderStack::execute_decode_stack()
srd_session_metadata_set(session, SRD_CONF_SAMPLERATE, srd_session_metadata_set(session, SRD_CONF_SAMPLERATE,
g_variant_new_uint64((uint64_t)_samplerate)); g_variant_new_uint64((uint64_t)_samplerate));
srd_pd_output_callback_add(session, SRD_OUTPUT_ANN, srd_pd_output_callback_add(
DecoderStack::annotation_callback, this); session,
SRD_OUTPUT_ANN,
DecoderStack::annotation_callback,
_stask_stauts);
char *error = NULL; char *error = NULL;
if (srd_session_start(session, &error) == SRD_OK) 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 //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(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); 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) { if (d->_no_memory) {
return; return;
} }

View File

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

View File

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

View File

@ -126,13 +126,6 @@ DevInst* SigSession::get_device()
return _dev_inst; 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 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); assert(dev_inst);
if (_dev_inst){ clear_all_decoder(false);
_dev_inst->dev_inst();
} RELEASE_ARRAY(_group_traces);
if (_dev_inst) { if (_dev_inst) {
sr_session_datafeed_callback_remove_all(); sr_session_datafeed_callback_remove_all();
_dev_inst->release(); _dev_inst->release();
_dev_inst = NULL;
} }
_dev_inst = dev_inst; _dev_inst = dev_inst;
RELEASE_ARRAY(_decode_traces);
RELEASE_ARRAY(_group_traces);
if (_dev_inst) { if (_dev_inst) {
try { try {
_dev_inst->use(this); _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 // Deslect the old device, because file type detection in File::create
// destorys the old session inside libsigrok. // 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 { try {
set_device(device::File::create(name)); set_device(device::File::create(name));
@ -196,6 +197,7 @@ void SigSession::close_file(DevInst *dev_inst)
assert(_device_manager); assert(_device_manager);
try { try {
clear_all_decoder();
dev_inst->device_updated(); dev_inst->device_updated();
set_repeating(false); set_repeating(false);
stop_capture(); stop_capture();
@ -500,13 +502,6 @@ void SigSession::sample_thread_proc(DevInst *dev_inst)
} }
void SigSession::stop_capture() void SigSession::stop_capture()
{
do_stop_capture();
int dex = 0;
clear_all_decode_task(dex);
}
void SigSession::do_stop_capture()
{ {
data_unlock(); data_unlock();
@ -689,7 +684,7 @@ void SigSession::init_signals()
// Clear the decode traces // Clear the decode traces
RELEASE_ARRAY(_decode_traces); clear_all_decoder();
// Detect what data types we will receive // Detect what data types we will receive
if(_dev_inst) { if(_dev_inst) {
@ -1786,7 +1781,7 @@ void SigSession::set_stop_scale(float scale)
_bClose = true; _bClose = true;
do_stop_capture(); //stop capture stop_capture(); //stop capture
clear_all_decoder(); //clear all decode task, and stop decode thread 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(); trace->decoder()->stop_decode_work();
} }
void SigSession::clear_all_decoder() void SigSession::clear_all_decoder(bool bUpdateView)
{ {
//create the wait task deque //create the wait task deque
int dex = -1; int dex = -1;
@ -1868,9 +1863,10 @@ void SigSession::set_stop_scale(float scale)
_decode_thread.join(); _decode_thread.join();
} }
if (!is_closed()) if (!is_closed() && bUpdateView){
signals_changed(); signals_changed();
} }
}
void SigSession::clear_all_decode_task(int &runningDex) 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. * Sets device instance that will be used in the next capture session.
*/ */
void set_device(DevInst *dev_inst); void set_device(DevInst *dev_inst);
void deselect_device();
void set_file(QString name); void set_file(QString name);
void close_file(DevInst *dev_inst); void close_file(DevInst *dev_inst);
void set_default_device(); void set_default_device();
@ -232,7 +232,7 @@ public:
sr_dev_inst* get_dev_inst_c(); sr_dev_inst* get_dev_inst_c();
void Open(); void Open();
void Close(); void Close();
void clear_all_decoder(); void clear_all_decoder(bool bUpdateView = true);
inline bool is_closed(){ inline bool is_closed(){
return _bClose; return _bClose;
@ -294,7 +294,6 @@ private:
view::DecodeTrace* get_top_decode_task(); view::DecodeTrace* get_top_decode_task();
void capture_init(); void capture_init();
void do_stop_capture();
void data_lock(); void data_lock();
void data_unlock(); void data_unlock();
void nodata_timeout(); void nodata_timeout();

View File

@ -740,7 +740,12 @@ void View::signals_changed()
const double height = (_time_viewport->height() const double height = (_time_viewport->height()
- 2 * actualMargin * label_size) * 1.0 / total_rows; - 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); GVariant* gvar = _session->get_device()->get_config(NULL, NULL, SR_CONF_MAX_HEIGHT_VALUE);
if (gvar != NULL) { if (gvar != NULL) {
max_height = (g_variant_get_byte(gvar) + 1) * MaxHeightUnit; max_height = (g_variant_get_byte(gvar) + 1) * MaxHeightUnit;