mirror of https://github.com/Genymobile/scrcpy
Process UHID outputs events from the main thread
This will guarantee that the callbacks of UHID devices implementations will always be called from the same (main) thread. PR #5270 <https://github.com/Genymobile/scrcpy/pull/5270>
This commit is contained in:
parent
72ee195693
commit
cbf5db85c1
|
@ -11,6 +11,13 @@
|
||||||
#include "util/str.h"
|
#include "util/str.h"
|
||||||
#include "util/thread.h"
|
#include "util/thread.h"
|
||||||
|
|
||||||
|
struct sc_uhid_output_task_data {
|
||||||
|
struct sc_uhid_devices *uhid_devices;
|
||||||
|
uint16_t id;
|
||||||
|
uint16_t size;
|
||||||
|
uint8_t *data;
|
||||||
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sc_receiver_init(struct sc_receiver *receiver, sc_socket control_socket,
|
sc_receiver_init(struct sc_receiver *receiver, sc_socket control_socket,
|
||||||
const struct sc_receiver_callbacks *cbs, void *cbs_userdata) {
|
const struct sc_receiver_callbacks *cbs, void *cbs_userdata) {
|
||||||
|
@ -54,6 +61,25 @@ task_set_clipboard(void *userdata) {
|
||||||
free(text);
|
free(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
task_uhid_output(void *userdata) {
|
||||||
|
assert(sc_thread_get_id() == SC_MAIN_THREAD_ID);
|
||||||
|
|
||||||
|
struct sc_uhid_output_task_data *data = userdata;
|
||||||
|
|
||||||
|
struct sc_uhid_receiver *uhid_receiver =
|
||||||
|
sc_uhid_devices_get_receiver(data->uhid_devices, data->id);
|
||||||
|
if (uhid_receiver) {
|
||||||
|
uhid_receiver->ops->process_output(uhid_receiver, data->data,
|
||||||
|
data->size);
|
||||||
|
} else {
|
||||||
|
LOGW("No UHID receiver for id %" PRIu16, data->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(data->data);
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
process_msg(struct sc_receiver *receiver, struct sc_device_msg *msg) {
|
process_msg(struct sc_receiver *receiver, struct sc_device_msg *msg) {
|
||||||
switch (msg->type) {
|
switch (msg->type) {
|
||||||
|
@ -112,18 +138,29 @@ process_msg(struct sc_receiver *receiver, struct sc_device_msg *msg) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sc_uhid_receiver *uhid_receiver =
|
struct sc_uhid_output_task_data *data = malloc(sizeof(*data));
|
||||||
sc_uhid_devices_get_receiver(receiver->uhid_devices,
|
if (!data) {
|
||||||
msg->uhid_output.id);
|
LOG_OOM();
|
||||||
if (uhid_receiver) {
|
return;
|
||||||
uhid_receiver->ops->process_output(uhid_receiver,
|
}
|
||||||
msg->uhid_output.data,
|
|
||||||
msg->uhid_output.size);
|
// It is guaranteed that these pointers will still be valid when
|
||||||
} else {
|
// the main thread will process them (the main thread will stop
|
||||||
LOGW("No UHID receiver for id %" PRIu16, msg->uhid_output.id);
|
// processing SC_EVENT_RUN_ON_MAIN_THREAD on exit, when everything
|
||||||
|
// gets deinitialized)
|
||||||
|
data->uhid_devices = receiver->uhid_devices;
|
||||||
|
data->id = msg->uhid_output.id;
|
||||||
|
data->data = msg->uhid_output.data; // take ownership
|
||||||
|
data->size = msg->uhid_output.size;
|
||||||
|
|
||||||
|
bool ok = sc_post_to_main_thread(task_uhid_output, data);
|
||||||
|
if (!ok) {
|
||||||
|
LOGW("Could not post UHID output to main thread");
|
||||||
|
free(data->data);
|
||||||
|
free(data);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sc_device_msg_destroy(msg);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue