fix life management of libusb_device*; add handler on exception to safe_thread

This commit is contained in:
gb 2023-11-24 15:39:24 +08:00
parent d73e068724
commit 9d9c38aaec
3 changed files with 18 additions and 6 deletions

View File

@ -82,7 +82,7 @@ int LIBUSB_CALL usb_manager::usb_pnp_callback(libusb_context* ctx, libusb_device
usb_manager* obj = (usb_manager*)monitor;
// if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED)
libusb_ref_device(device); // keep the object until handle it
//libusb_ref_device(device); // keep the object until handle it
//else if(event == LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT)
// libusb_unref_device(device);
@ -206,17 +206,22 @@ void usb_manager::thread_notify_usb_event()
}
}
libusb_ref_device(pd.dev); // for re-enter the queue pnp_events_
notify_usb_event(pd, &retry);
if (retry)
{
if(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - pd.happen_time).count()
<= 5000)
pnp_events_.Put(pd, sizeof(pd));
else
retry = false;
if(pnp_events_.Size() == 1)
this_thread::sleep_for(chrono::milliseconds(1000));
else
this_thread::sleep_for(chrono::milliseconds(delay));
}
if (!retry)
libusb_unref_device(pd.dev);
}
}
}
@ -311,6 +316,7 @@ int usb_manager::on_usb_pnp_event(libusb_context *ctx, libusb_device *device, li
PNPDEV pd;
unsigned ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - born_).count();
libusb_ref_device(device);
pd.ctx = ctx;
pd.dev = device;
pd.event = event;
@ -323,9 +329,12 @@ int usb_manager::on_usb_pnp_event(libusb_context *ctx, libusb_device *device, li
else
{
bool retry = false;
libusb_ref_device(device);
notify_usb_event(pd, &retry);
if(retry)
pnp_events_.Put(pd, sizeof(pd));
else
libusb_unref_device(device);
}
return 0;

View File

@ -1854,11 +1854,12 @@ safe_thread::~safe_thread()
thread_->join();
}
void safe_thread::thread_worker(std::function<void(void*)> func, void* param)
void safe_thread::thread_worker(std::function<void(void*)> func, void* param, std::function<void(void)> on_exception)
{
try
{
func(param);
return;
}
catch (std::exception e)
{
@ -1868,15 +1869,17 @@ void safe_thread::thread_worker(std::function<void(void*)> func, void* param)
{
utils::to_log(LOG_LEVEL_FATAL, "Unknown exception in thread '%s'!\n", name_.c_str());
}
if (on_exception)
on_exception();
}
int safe_thread::start(std::function<void(void*)> f, void* param, const char* thread_name)
int safe_thread::start(std::function<void(void*)> f, void* param, const char* thread_name, std::function<void(void)> on_exception)
{
if (thread_.get() && thread_->joinable())
thread_->join();
name_ = thread_name ? thread_name : "";
thread_.reset(new std::thread(&safe_thread::thread_worker, this, f, param));
thread_.reset(new std::thread(&safe_thread::thread_worker, this, f, param, on_exception));
return 0;
}

View File

@ -345,12 +345,12 @@ class safe_thread
std::unique_ptr<std::thread> thread_;
std::string name_;
void thread_worker(std::function<void(void*)> func, void* param);
void thread_worker(std::function<void(void*)> func, void* param, std::function<void(void)> on_exception);
public:
safe_thread(void);
~safe_thread();
public:
int start(std::function<void(void*)> f, void* param, const char* thread_name);
int start(std::function<void(void*)> f, void* param, const char* thread_name, std::function<void(void)> on_exception = std::function<void(void)>());
};