Unify libusb event threads

This commit is contained in:
Lorenzooone 2025-03-26 13:48:33 +01:00
parent 7893e0b022
commit 781157987f
12 changed files with 49 additions and 115 deletions

View File

@ -16,8 +16,6 @@ enum ftd2_flow_ctrls {
void ftd2_libusb_init();
void ftd2_libusb_end();
void ftd2_libusb_start_thread(std::thread* thread_ptr, bool* usb_thread_run);
void ftd2_libusb_close_thread(std::thread* thread_ptr, bool* usb_thread_run);
// Generic functions
void list_devices_ftd2_libusb(std::vector<CaptureDevice> &devices_list, std::vector<no_access_recap_data> &no_access_list);

View File

@ -5,8 +5,6 @@
#include "capture_structs.hpp"
#include "cypress_nisetro_communications.hpp"
void cypress_libusb_start_thread(std::thread* thread_ptr, bool* usb_thread_run);
void cypress_libusb_close_thread(std::thread* thread_ptr, bool* usb_thread_run);
void cypress_libusb_list_devices(std::vector<CaptureDevice> &devices_list, bool* no_access_elems, bool* not_supported_elems, int *curr_serial_extra_id_cypress, const size_t num_cypress_desc);
cyni_device_device_handlers* cypress_libusb_serial_reconnection(const cyni_device_usb_device* usb_device_desc, std::string wanted_serial_number, int &curr_serial_extra_id, CaptureDevice* new_device);
void cypress_libusb_find_used_serial(const cyni_device_usb_device* usb_device_desc, bool* found, size_t num_free_fw_ids, int &curr_serial_extra_id);

View File

@ -13,4 +13,7 @@ int get_usb_total_filtered_devices(const uint16_t valid_vids[], size_t num_vids,
void libusb_check_and_detach_kernel_driver(void* handle, int interface);
int libusb_check_and_set_configuration(void* handle, int wanted_configuration);
void libusb_register_to_event_thread();
void libusb_unregister_from_event_thread();
#endif

View File

@ -4,7 +4,6 @@
#include "3dscapture_ftd3_shared_general.hpp"
#include "devicecapture.hpp"
#include <thread>
#include <libusb.h>
#include "usb_generic.hpp"
@ -36,30 +35,6 @@ struct FTD3LibusbCaptureReceivedData {
static void ftd3_libusb_read_frame_cb(void* user_data, int transfer_length, int transfer_status);
static void ftd3_device_usb_thread_function(bool* usb_thread_run) {
if(!usb_is_initialized())
return;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 300000;
while(*usb_thread_run)
libusb_handle_events_timeout_completed(get_usb_ctx(), &tv, NULL);
}
static void ftd3_libusb_start_thread(std::thread* thread_ptr, bool* usb_thread_run) {
if(!usb_is_initialized())
return;
*usb_thread_run = true;
*thread_ptr = std::thread(ftd3_device_usb_thread_function, usb_thread_run);
}
static void ftd3_libusb_close_thread(std::thread* thread_ptr, bool* usb_thread_run) {
if(!usb_is_initialized())
return;
*usb_thread_run = false;
thread_ptr->join();
}
static int get_ftd3_libusb_status(FTD3LibusbCaptureReceivedData* ftd3_libusb_capture_recv_data) {
return *ftd3_libusb_capture_recv_data[0].status;
}
@ -239,8 +214,6 @@ static void ftd3_libusb_capture_main_loop_processing(FTD3LibusbCaptureReceivedDa
void ftd3_libusb_capture_main_loop(CaptureData* capture_data, int pipe) {
if(!usb_is_initialized())
return;
bool is_done_thread;
std::thread async_processing_thread;
uint32_t last_index = -1;
int status = 0;
@ -261,9 +234,9 @@ void ftd3_libusb_capture_main_loop(CaptureData* capture_data, int pipe) {
ftd3_libusb_capture_recv_data[i].cb_data.actual_user_data = &ftd3_libusb_capture_recv_data[i];
ftd3_libusb_capture_recv_data[i].cb_data.transfer_data = NULL;
}
ftd3_libusb_start_thread(&async_processing_thread, &is_done_thread);
libusb_register_to_event_thread();
ftd3_libusb_capture_main_loop_processing(ftd3_libusb_capture_recv_data, pipe);
wait_all_ftd3_libusb_buffers_free(ftd3_libusb_capture_recv_data);
ftd3_libusb_close_thread(&async_processing_thread, &is_done_thread);
libusb_unregister_from_event_thread();
delete []ftd3_libusb_capture_recv_data;
}

View File

@ -319,9 +319,8 @@ void ftd2_capture_main_loop_libusb(CaptureData* capture_data) {
size_t curr_offset = 0;
const size_t full_size = get_capture_size(capture_data->status.device.is_rgb_888);
size_t bytesIn;
bool usb_thread_run = false;
std::thread processing_thread;
ftd2_libusb_start_thread(&processing_thread, &usb_thread_run);
libusb_register_to_event_thread();
SharedConsumerMutex is_buffer_free_shared_mutex(NUM_CAPTURE_RECEIVED_DATA_BUFFERS);
SharedConsumerMutex is_transfer_done_mutex(NUM_CAPTURE_RECEIVED_DATA_BUFFERS);
@ -365,6 +364,6 @@ void ftd2_capture_main_loop_libusb(CaptureData* capture_data) {
resync_offset(received_data_buffers, index, full_size);
}
wait_all_ftd2_libusb_buffers_free(received_data_buffers);
ftd2_libusb_close_thread(&processing_thread, &usb_thread_run);
libusb_unregister_from_event_thread();
delete []received_data_buffers;
}

View File

@ -61,30 +61,6 @@ void ftd2_libusb_end() {
usb_close();
}
static void ftd2_libusb_usb_thread_function(bool* usb_thread_run) {
if(!usb_is_initialized())
return;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 300000;
while(*usb_thread_run)
libusb_handle_events_timeout_completed(get_usb_ctx(), &tv, NULL);
}
void ftd2_libusb_start_thread(std::thread* thread_ptr, bool* usb_thread_run) {
if(!usb_is_initialized())
return;
*usb_thread_run = true;
*thread_ptr = std::thread(ftd2_libusb_usb_thread_function, usb_thread_run);
}
void ftd2_libusb_close_thread(std::thread* thread_ptr, bool* usb_thread_run) {
if(!usb_is_initialized())
return;
*usb_thread_run = false;
thread_ptr->join();
}
static int read_strings(libusb_device_handle *handle, libusb_device_descriptor *usb_descriptor, char* manufacturer, char* description, char* serial) {
manufacturer[0] = 0;
description[0] = 0;

View File

@ -4,6 +4,7 @@
#include "usb_is_device_is_driver.hpp"
#include "is_twl_cap_init_seed_table.h"
#include "is_twl_cap_crc32_table.h"
#include "usb_generic.hpp"
#include <libusb.h>
#include <cstring>
@ -1308,12 +1309,12 @@ int PrepareEncDecTable(is_device_device_handlers* handlers, is_device_twl_enc_de
void SetupISDeviceAsyncThread(is_device_device_handlers* handlers, void* user_data, std::thread* thread_ptr, bool* keep_going, ConsumerMutex* is_data_ready) {
if(handlers->usb_handle)
return is_device_libusb_start_thread(thread_ptr, keep_going);
return libusb_register_to_event_thread();
return is_device_is_driver_start_thread(thread_ptr, keep_going, (ISDeviceCaptureReceivedData*)user_data, handlers, is_data_ready);
}
void EndISDeviceAsyncThread(is_device_device_handlers* handlers, void* user_data, std::thread* thread_ptr, bool* keep_going, ConsumerMutex* is_data_ready) {
if(handlers->usb_handle)
return is_device_libusb_close_thread(thread_ptr, keep_going);
return libusb_unregister_from_event_thread();
return is_device_is_driver_close_thread(thread_ptr, keep_going, (ISDeviceCaptureReceivedData*)user_data);
}

View File

@ -25,30 +25,6 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
static void is_device_usb_thread_function(bool* usb_thread_run) {
if(!usb_is_initialized())
return;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 300000;
while(*usb_thread_run)
libusb_handle_events_timeout_completed(get_usb_ctx(), &tv, NULL);
}
void is_device_libusb_start_thread(std::thread* thread_ptr, bool* usb_thread_run) {
if(!usb_is_initialized())
return;
*usb_thread_run = true;
*thread_ptr = std::thread(is_device_usb_thread_function, usb_thread_run);
}
void is_device_libusb_close_thread(std::thread* thread_ptr, bool* usb_thread_run) {
if(!usb_is_initialized())
return;
*usb_thread_run = false;
thread_ptr->join();
}
static bool is_device_libusb_setup_connection(libusb_device_handle* handle, const is_device_usb_device* usb_device_desc) {
libusb_check_and_detach_kernel_driver(handle, usb_device_desc->default_interface);
int result = libusb_check_and_set_configuration(handle, usb_device_desc->default_config);

View File

@ -4,6 +4,7 @@
#include "cypress_nisetro_driver_comms.hpp"
#include "cypress_nisetro_acquisition_general.hpp"
#include "nisetro_ds_fw.h"
#include "usb_generic.hpp"
#include <libusb.h>
#include <cstring>
@ -245,12 +246,12 @@ void CloseAsyncRead(cyni_device_device_handlers* handlers, const cyni_device_usb
void SetupCypressDeviceAsyncThread(cyni_device_device_handlers* handlers, void* user_data, std::thread* thread_ptr, bool* keep_going, ConsumerMutex* is_data_ready) {
if(handlers->usb_handle)
return cypress_libusb_start_thread(thread_ptr, keep_going);
return libusb_register_to_event_thread();
return cypress_driver_start_thread(thread_ptr, keep_going, (CypressDeviceCaptureReceivedData*)user_data, handlers, is_data_ready);
}
void EndCypressDeviceAsyncThread(cyni_device_device_handlers* handlers, void* user_data, std::thread* thread_ptr, bool* keep_going, ConsumerMutex* is_data_ready) {
if(handlers->usb_handle)
return cypress_libusb_close_thread(thread_ptr, keep_going);
return libusb_unregister_from_event_thread();
return cypress_driver_close_thread(thread_ptr, keep_going, (CypressDeviceCaptureReceivedData*)user_data);
}

View File

@ -5,30 +5,6 @@
#include <libusb.h>
#include "usb_generic.hpp"
static void cypress_device_usb_thread_function(bool* usb_thread_run) {
if(!usb_is_initialized())
return;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 300000;
while(*usb_thread_run)
libusb_handle_events_timeout_completed(get_usb_ctx(), &tv, NULL);
}
void cypress_libusb_start_thread(std::thread* thread_ptr, bool* usb_thread_run) {
if(!usb_is_initialized())
return;
*usb_thread_run = true;
*thread_ptr = std::thread(cypress_device_usb_thread_function, usb_thread_run);
}
void cypress_libusb_close_thread(std::thread* thread_ptr, bool* usb_thread_run) {
if(!usb_is_initialized())
return;
*usb_thread_run = false;
thread_ptr->join();
}
// Read from ctrl_in
int cypress_libusb_ctrl_in(cyni_device_device_handlers* handlers, const cyni_device_usb_device* usb_device_desc, uint8_t* buf, int length, uint8_t request, uint16_t value, uint16_t index, int* transferred) {
int ret = libusb_control_transfer(handlers->usb_handle, 0xC0, request, value, index, buf, length, usb_device_desc->bulk_timeout);

View File

@ -4,7 +4,6 @@
#include <libusb.h>
#include <cstring>
#include <thread>
#include <chrono>
#include <iostream>

View File

@ -1,9 +1,12 @@
#include "usb_generic.hpp"
#include <thread>
#include <mutex>
static bool usb_thread_run = false;
static bool usb_initialized = false;
static libusb_context* usb_ctx = NULL; // libusb session context
static int usb_thread_registered = 0;
std::thread usb_thread;
std::mutex usb_thread_mutex;
void usb_init() {
if(usb_initialized)
@ -87,3 +90,34 @@ int libusb_check_and_set_configuration(void* handle, int wanted_configuration) {
result = libusb_set_configuration(in_handle, wanted_configuration);
return result;
}
static void libusb_usb_thread_function() {
if(!usb_is_initialized())
return;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 300000;
while(usb_thread_registered > 0)
libusb_handle_events_timeout_completed(get_usb_ctx(), &tv, NULL);
}
void libusb_register_to_event_thread() {
if(!usb_is_initialized())
return;
usb_thread_mutex.lock();
int old_usb_thread_registered = usb_thread_registered;
usb_thread_registered += 1;
if(old_usb_thread_registered == 0)
usb_thread = std::thread(libusb_usb_thread_function);
usb_thread_mutex.unlock();
}
void libusb_unregister_from_event_thread() {
if(!usb_is_initialized())
return;
usb_thread_mutex.lock();
usb_thread_registered -= 1;
if(usb_thread_registered == 0)
usb_thread.join();
usb_thread_mutex.unlock();
}