mirror of
https://github.com/DreamSourceLab/DSView.git
synced 2025-01-13 13:32:53 +08:00
fix: Safely remove decode tasks
This commit is contained in:
parent
5fe37c7d62
commit
c3ab42fcf5
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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:
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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();
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user