调整sane_start/sane_stop流程,start等到一张图后返回第一张图状态或者结束状态;stop等到工作线程退出后才返回

This commit is contained in:
gb 2023-10-28 14:47:15 +08:00
parent 3af53b5dae
commit 927b0199d3
12 changed files with 182 additions and 58 deletions

View File

@ -3459,9 +3459,22 @@ int hg_scanner::try_third_app_handle_start(bool& handled)
{
int ret = SCANNER_ERR_OK;
handled = false;
return ret;
handled = !async_io_;
if (handled)
{
if (user_cancel_)
{
if (status_ != SCANNER_ERR_OK && status_ != SCANNER_ERR_USER_CANCELED) // call stop after exception occurs, start a new scanning ...
{
handled = false;
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "call start after user cancelled while status is %s, we start a new scanning\n", hg_scanner_err_description(status_));
return ret;
}
}
while (wait_usb_result_.try_wait())
std::this_thread::sleep_for(std::chrono::milliseconds(3));
@ -3505,13 +3518,14 @@ int hg_scanner::try_third_app_handle_start(bool& handled)
}
int hg_scanner::try_third_app_after_start(int err)
{
if (!async_io_)
{
while (wait_img_.is_waiting() && !wait_usb_.is_waiting())
std::this_thread::sleep_for(std::chrono::milliseconds(10));
if (wait_img_.is_waiting() && wait_usb_.is_waiting())
err = status_;
}
//if (!async_io_)
//{
// while (wait_img_.is_waiting() && !wait_usb_.is_waiting())
// std::this_thread::sleep_for(std::chrono::milliseconds(10));
// if (wait_img_.is_waiting() && wait_usb_.is_waiting())
// err = status_;
//
//}
return err;
}
@ -3609,7 +3623,7 @@ int hg_scanner::save_usb_data(std::shared_ptr<tiny_buffer> data)
unsigned int bytes = data->size();
usb_img_index_++;
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "USB read one picture with %u bytes\n", data->size());
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "USB packet(%04d) of picture with %u bytes(status: %d)\n", usb_img_index_, data->size(), data->get_image_statu());
if (dump_usb_path_.length()) //这两台设备不是jpg的图 所以不能直接处理
{
char name[80] = { 0 };
@ -4081,11 +4095,98 @@ void hg_scanner::on_language_changed(void)
}
}
}
int hg_scanner::wait_one_image_from_start(bool& handled)
{
int ret = SCANNER_ERR_OK;
handled = false;
if (!async_io_) // non-callback
{
while (is_running() != THREAD_RUNNING_IDLE)
{
handled = true;
if (final_imgs_.size())
{
break;
}
}
if (final_imgs_.size())
{
IMH head = { 0 };
handled = true;
if (final_imgs_.front(&head))
{
if (head.statu & IMG_STATUS_DOUBLE)
ret = SCANNER_ERR_DEVICE_DOUBLE_FEEDING;
else if (head.statu & IMG_STATUS_JAM)
ret = SCANNER_ERR_DEVICE_PAPER_JAMMED;
else if (head.statu & IMG_STATUS_STAPLE)
ret = SCANNER_ERR_DEVICE_STAPLE_ON;
else if (head.statu & IMG_STATUS_SIZE_ERR)
ret = SCANNER_ERR_DEVICE_SIZE_CHECK;
else if (head.statu & IMG_STATUS_DOGEAR)
ret = SCANNER_ERR_DEVICE_DOGEAR;
}
}
else if (handled) // overed normal or exception
{
if (status_ == SCANNER_ERR_OK
|| status_ == SCANNER_ERR_DEVICE_DOUBLE_FEEDING) // 双张特殊处理,视为成功
{
SANE_Bool has_paper = SANE_FALSE;
get_scanner_paperon(has_paper);
if (has_paper == SANE_TRUE)
handled = false;
else
ret = SCANNER_ERR_DEVICE_NO_PAPER;
}
else
ret = status_;
}
}
return ret;
}
int hg_scanner::start(void)
{
user_cancel_ = false;
int ret = SCANNER_ERR_OK;
bool handled = false;
return status_;
if (user_cancel_)
{
user_cancel_ = false; // stopped by user, reset flag and starting a new scanning ...
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "start after user stopped just now while with %d image(s) in queue, a new scanning will to be started ...\n", final_imgs_.size());
}
else
{
ret = wait_one_image_from_start(handled);
if (handled)
{
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "start in previous scanning and result is %s, image count %d\n", hg_scanner_err_description(ret), final_imgs_.size());
return ret;
}
}
// clear ...
imgs_.Clear();
final_imgs_.clear();
usb_img_index_ = final_img_index_ = 0;
status_ = SCANNER_ERR_OK;
// start ...
ret = do_start();
if (ret == SCANNER_ERR_OK)
{
// wait ONE picture or stopped
ret = wait_one_image_from_start(handled);
}
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "start scanning result = %s\n", hg_scanner_err_description(ret));
return ret;
}
int hg_scanner::get_image_info(SANE_Parameters* ii, int len)
{
@ -4197,9 +4298,21 @@ int hg_scanner::read_image_data(unsigned char* buf, int* len)
}
int hg_scanner::stop(void)
{
user_cancel_ = true;
int ret = SCANNER_ERR_OK;
return status_;
user_cancel_ = true;
ret = do_stop();
// wait until really stopped ...
if (ret == SCANNER_ERR_OK)
{
while (is_running() != THREAD_RUNNING_IDLE)
std::this_thread::sleep_for(std::chrono::milliseconds(3));
ret = status_;
}
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "user stopped result = %s\n", hg_scanner_err_description(ret));
return ret;
}
int hg_scanner::reset(void)
{

View File

@ -439,6 +439,7 @@ protected:
int save_final_image(hg_imgproc::LPIMGHEAD head, void* buf, uint32_t id = -1);
void adjust_filling_hole(LPSCANCONF conf);
int wait_one_image_from_start(bool& handled);
////////////////////////////////////////////////////////////////
// 新增自定义伽玛曲线及扫描区域属性 - 2022-05-05
@ -461,6 +462,9 @@ protected:
bool is_white_0_; // 是否0代表白色
public:
int start(void);
int stop(void);
void set_ui_callback(sane_callback cb, bool enable_async_io);
void set_dev_family(const char* family);
void set_read_over_with_no_data(bool no_data);
@ -487,10 +491,10 @@ public:
int is_running(void); // return thread_running
public:
virtual int start(void);
virtual int do_start(void) = 0;
virtual int do_stop(void) = 0;
virtual int get_image_info(SANE_Parameters* ii, int len);
virtual int read_image_data(unsigned char* buf, int* len);
virtual int stop(void);
virtual int reset(void);
virtual int device_io_control(unsigned long code, void* data, unsigned* len);
virtual int discard_all_images(void) = 0;

View File

@ -265,7 +265,7 @@ void hg_scanner_200::thread_handle_usb_read(void)
}
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "USB thread exit with code: %s, status = %s\n", hg_scanner_err_name(ret), hg_scanner_err_description(status_));
}
int hg_scanner_200::start(void)
int hg_scanner_200::do_start(void)
{
bool handled = false;
int ret = try_third_app_handle_start(handled),
@ -318,7 +318,7 @@ int hg_scanner_200::start(void)
return ret;
}
int hg_scanner_200::stop(void)
int hg_scanner_200::do_stop(void)
{
int ret = SCANNER_ERR_OK;
@ -337,7 +337,8 @@ int hg_scanner_200::stop(void)
{
status_ = SCANNER_ERR_DEVICE_STOPPED;
}
return status_;
return ret;
}
int hg_scanner_200::writeusb(USBCB &usb)
{

View File

@ -50,8 +50,8 @@ public:
~hg_scanner_200();
public:
virtual int start(void)override;
virtual int stop(void)override;
virtual int do_start(void) override;
virtual int do_stop(void) override;
private:
int initdevice();

View File

@ -1337,6 +1337,7 @@ void hg_scanner_239::thread_get_dves_image(void)
{
std::lock_guard<std::mutex> lock(io_lock_);
memset(buf, 0, size);
ret = io_->read_interrupt(buf, &size);
io_->set_timeout(1000);
}
@ -1354,7 +1355,7 @@ void hg_scanner_239::thread_get_dves_image(void)
if (is_auto_paper_scan && sw.elapsed_s() >= is_auto_paper_scan_exit_time && is_auto_paper_scan_exit_time != 0)
{
stop();
do_stop();
notify_ui_working_status(from_default_language(STATU_DESC_SCANNER_ERR_DEVICE_EXIT_WAIT_SCAN), SANE_EVENT_ERROR, status_);
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "auto paper scan exit :%s\n", from_default_language(STATU_DESC_SCANNER_ERR_DEVICE_EXIT_WAIT_SCAN));
}
@ -1397,7 +1398,7 @@ void hg_scanner_239::thread_get_dves_image(void)
&& status_ != SCANNER_ERR_DEVICE_AUTO_FAIL_INFO
)
{
if (info->From != setting3399::IMG && status_ != SCANNER_ERR_DEVICE_DOUBLE_FEEDING)
if (info->From != setting3399::IMG /*&& status_ != SCANNER_ERR_DEVICE_DOUBLE_FEEDING*/)
svdevs_err_.push_back(status_);
}
@ -1413,13 +1414,13 @@ void hg_scanner_239::thread_get_dves_image(void)
while (get_image_count() > 0)
{
ret = read_one_image_from_usb((status_ == SCANNER_ERR_DEVICE_DOUBLE_FEEDING && dev_conf_.params_3399.double_out_en) ? IMG_STATUS_DOUBLE : IMG_STATUS_OK);
ret = read_one_image_from_usb((status_ == SCANNER_ERR_DEVICE_DOUBLE_FEEDING /*&& dev_conf_.params_3399.double_out_en*/) ? IMG_STATUS_DOUBLE : IMG_STATUS_OK);
//if (status_ == SCANNER_ERR_DEVICE_DOUBLE_FEEDING)
// svdevs_err_.push_back(IMG_STATUS_DOUBLE);
count++;
if (ret != SCANNER_ERR_OK
&& ret != SCANNER_ERR_CREATE_FILE_FAILED
&& ret != SCANNER_ERR_WRITE_FILE_FAILED)
//if (ret != SCANNER_ERR_OK
// && ret != SCANNER_ERR_CREATE_FILE_FAILED
// && ret != SCANNER_ERR_WRITE_FILE_FAILED)
break;
}
}
@ -1441,15 +1442,22 @@ void hg_scanner_239::thread_get_dves_image(void)
else
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
int rest = 0;
while (get_image_count() > 0)
{
ret = read_one_image_from_usb();
count++;
rest++;
if (ret != SCANNER_ERR_OK
&& ret != SCANNER_ERR_CREATE_FILE_FAILED
&& ret != SCANNER_ERR_WRITE_FILE_FAILED)
break;
}
count += rest;
if (rest)
{
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "STOPSCAN message is ahead of %d image(s)!\n", rest);
}
if (user_cancel_ && !is_auto_paper_scan)
{
if (status_ && status_ != SCANNER_ERR_DEVICE_STOPPED) // thread_handle_image_process maybe call stop() when insufficient memory occurs .
@ -1492,7 +1500,7 @@ void hg_scanner_239::thread_get_dves_image(void)
else if (info->From == setting3399::V4L2)
{
VLOG_MINI_2(LOG_LEVEL_WARNING, "V4L2 message received, code = %d, index = %d\n", info->Code, info->Img_Index);
// stop();
// do_stop();
break;
}
else if (info->From == setting3399::AutoCorrect)
@ -1526,7 +1534,7 @@ void hg_scanner_239::thread_handle_usb_read(void)
thread_get_dves_image();
}
int hg_scanner_239::start(void)
int hg_scanner_239::do_start(void)
{
bool handled = false;
int ret = try_third_app_handle_start(handled),
@ -1536,8 +1544,6 @@ int hg_scanner_239::start(void)
return ret;
user_cancel_ = false;
split3399_ = 0;
cb_mem_ = true;
@ -1614,15 +1620,14 @@ int hg_scanner_239::start(void)
return ret;
}
int hg_scanner_239::stop(void)
int hg_scanner_239::do_stop(void)
{
int ret = SCANNER_ERR_OK;
user_cancel_ = true;
ret = write_command(setting3399::SC_STOP);
io_->set_timeout(500);
return status_;
return ret;
}
int hg_scanner_239::reset(void)
{
@ -1824,9 +1829,9 @@ int hg_scanner_239::get_scanner_paperon(SANE_Bool& type)
int ret = read_register(setting3399::SR_GET_PAPERON, &val); //0无纸 1有纸
if (ret == SCANNER_ERR_OK)
{
type = val == 0 ? false : true;
type = val == 0 ? SANE_FALSE : SANE_TRUE;
}
VLOG_MINI_1(LOG_LEVEL_WARNING, "get_scanner_paperon is(%s)\n", !type ? hg_scanner_err_description(SCANNER_ERR_DEVICE_NO_PAPER) : hg_scanner_err_description(SCANNER_ERR_OK));
VLOG_MINI_1(LOG_LEVEL_WARNING, "get_scanner_paperon is(%s)\n", val == 0 ? hg_scanner_err_description(SCANNER_ERR_DEVICE_NO_PAPER) : "paper on");
return ret;
}

View File

@ -86,8 +86,8 @@ public:
public:
//virtual int get_image_info(IMG_PARAM* ii) override;
//virtual int read_image_data(unsigned char* buf, int* len) override;
virtual int start(void) override;
virtual int stop(void) override;
virtual int do_start(void) override;
virtual int do_stop(void) override;
virtual int reset(void) override;
virtual int device_io_control(unsigned long code, void* data, unsigned* len) override;
virtual int get_roller_life(void) override;

View File

@ -334,7 +334,7 @@ int hg_scanner_300::get_roller_life(void)
{
return pid_ == 300 ? 150000 : 200000;
}
int hg_scanner_300::start(void)
int hg_scanner_300::do_start(void)
{
bool handled = false;
int ret = try_third_app_handle_start(handled), //sane调用是每次都会调用一次start和stop
@ -408,7 +408,7 @@ int hg_scanner_300::start(void)
VLOG_MINI_1(LOG_LEVEL_WARNING, "----------Main start scan status : %s----------\n", hg_scanner_err_description(ret));
return ret;
}
int hg_scanner_300::stop(void)
int hg_scanner_300::do_stop(void)
{
int ret = SCANNER_ERR_OK;
@ -431,7 +431,7 @@ int hg_scanner_300::stop(void)
}
//final_imgs_.clear();
return status_;
return ret;
}
int hg_scanner_300::writeusb(USBCB &usb)
{
@ -554,7 +554,7 @@ int hg_scanner_300::get_img_data(std::shared_ptr<tiny_buffer>& imagedata)
else
{
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Read image data from USB err: %s\n", hg_scanner_err_name(ret));
stop();
do_stop();
string str = STATU_DESC_SCANNER_ERR_DEVICE_GET_IMAGE_ERR;
str = str + '-' + STATU_DESC_SCANNER_ERR_DEVICE_STOPPED;
notify_ui_working_status(str.c_str(), SANE_EVENT_ERROR, ret);

View File

@ -51,8 +51,9 @@ public:
hg_scanner_300(const char* dev_name,int pid, usb_io* io);
~hg_scanner_300();
public:
virtual int start(void)override;
virtual int stop(void)override;
virtual int do_start(void) override;
virtual int do_stop(void) override;
private:
int set_kernelsnap_ver();
int agreement(TwSS tw,int align);

View File

@ -1020,7 +1020,7 @@ void hg_scanner_302::thread_handle_usb_read(void)
VLOG_MINI_1(LOG_LEVEL_FATAL, "V4L2 error: %d\n", info->Code);
{
bool cancel = user_cancel_;
stop();
do_stop();
user_cancel_ = cancel;
go = false;
}
@ -1052,7 +1052,7 @@ void hg_scanner_302::thread_handle_usb_read(void)
}
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "USB thread exit with code: %s, status = %s\n", hg_scanner_err_name(ret), hg_scanner_err_name(status_));
}
int hg_scanner_302::start(void)
int hg_scanner_302::do_start(void)
{
bool handled = false;
@ -1129,7 +1129,7 @@ int hg_scanner_302::start(void)
return ret;
}
int hg_scanner_302::stop(void)
int hg_scanner_302::do_stop(void)
{
std::lock_guard<std::mutex> lock(io_lock_);
int ret = SCANNER_ERR_OK;
@ -1139,7 +1139,7 @@ int hg_scanner_302::stop(void)
// io_->set_timeout(500);
//final_imgs_.clear();
return status_;
return ret;
}
int hg_scanner_302::reset(void)
{

View File

@ -83,10 +83,9 @@ public:
~hg_scanner_302();
public:
virtual int start(void) override;
//virtual int get_image_info(IMG_PARAM* ii) override;
//virtual int read_image_data(unsigned char* buf, int* len) override;
virtual int stop(void) override;
virtual int do_start(void) override;
virtual int do_stop(void) override;
virtual int reset(void) override;
virtual int device_io_control(unsigned long code, void* data, unsigned* len) override;

View File

@ -294,7 +294,7 @@ int hg_scanner_306::get_roller_life(void)
{
return pid_ == 300 ? 150000 : 200000;
}
int hg_scanner_306::start(void)
int hg_scanner_306::do_start(void)
{
bool handled = false;
int ret = try_third_app_handle_start(handled), //sane调用是每次都会调用一次start和stop
@ -368,7 +368,7 @@ int hg_scanner_306::start(void)
VLOG_MINI_1(LOG_LEVEL_WARNING, "----------Main start scan status : %s----------\n", hg_scanner_err_description(ret));
return ret;
}
int hg_scanner_306::stop(void)
int hg_scanner_306::do_stop(void)
{
int ret = SCANNER_ERR_OK;
@ -391,7 +391,7 @@ int hg_scanner_306::stop(void)
}
//final_imgs_.clear();
return status_;
return ret;
}
int hg_scanner_306::writeusb(USBCB &usb)
{

View File

@ -52,8 +52,9 @@ public:
hg_scanner_306(const char* dev_name,int pid, usb_io* io);
~hg_scanner_306();
public:
virtual int start(void)override;
virtual int stop(void)override;
virtual int do_start(void) override;
virtual int do_stop(void) override;
private:
int set_kernelsnap_ver();
int agreement(TwSS tw,int align);