Terminate on controller error
This is particularly important to react to server socket disconnection since video and audio may be disabled. PR #4868 <https://github.com/Genymobile/scrcpy/pull/4868>
This commit is contained in:
parent
b5c8de08e0
commit
063a8339ed
@ -6,8 +6,19 @@
|
|||||||
|
|
||||||
#define SC_CONTROL_MSG_QUEUE_MAX 64
|
#define SC_CONTROL_MSG_QUEUE_MAX 64
|
||||||
|
|
||||||
|
static void
|
||||||
|
sc_controller_receiver_on_error(struct sc_receiver *receiver, void *userdata) {
|
||||||
|
(void) receiver;
|
||||||
|
|
||||||
|
struct sc_controller *controller = userdata;
|
||||||
|
// Forward the event to the controller listener
|
||||||
|
controller->cbs->on_error(controller, controller->cbs_userdata);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sc_controller_init(struct sc_controller *controller, sc_socket control_socket) {
|
sc_controller_init(struct sc_controller *controller, sc_socket control_socket,
|
||||||
|
const struct sc_controller_callbacks *cbs,
|
||||||
|
void *cbs_userdata) {
|
||||||
sc_vecdeque_init(&controller->queue);
|
sc_vecdeque_init(&controller->queue);
|
||||||
|
|
||||||
bool ok = sc_vecdeque_reserve(&controller->queue, SC_CONTROL_MSG_QUEUE_MAX);
|
bool ok = sc_vecdeque_reserve(&controller->queue, SC_CONTROL_MSG_QUEUE_MAX);
|
||||||
@ -15,7 +26,12 @@ sc_controller_init(struct sc_controller *controller, sc_socket control_socket) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = sc_receiver_init(&controller->receiver, control_socket);
|
static const struct sc_receiver_callbacks receiver_cbs = {
|
||||||
|
.on_error = sc_controller_receiver_on_error,
|
||||||
|
};
|
||||||
|
|
||||||
|
ok = sc_receiver_init(&controller->receiver, control_socket, &receiver_cbs,
|
||||||
|
controller);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
sc_vecdeque_destroy(&controller->queue);
|
sc_vecdeque_destroy(&controller->queue);
|
||||||
return false;
|
return false;
|
||||||
@ -39,6 +55,10 @@ sc_controller_init(struct sc_controller *controller, sc_socket control_socket) {
|
|||||||
controller->control_socket = control_socket;
|
controller->control_socket = control_socket;
|
||||||
controller->stopped = false;
|
controller->stopped = false;
|
||||||
|
|
||||||
|
assert(cbs && cbs->on_error);
|
||||||
|
controller->cbs = cbs;
|
||||||
|
controller->cbs_userdata = cbs_userdata;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,10 +145,16 @@ run_controller(void *data) {
|
|||||||
sc_control_msg_destroy(&msg);
|
sc_control_msg_destroy(&msg);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
LOGD("Could not write msg to socket");
|
LOGD("Could not write msg to socket");
|
||||||
break;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
controller->cbs->on_error(controller, controller->cbs_userdata);
|
||||||
|
|
||||||
|
return 1; // ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -22,10 +22,19 @@ struct sc_controller {
|
|||||||
bool stopped;
|
bool stopped;
|
||||||
struct sc_control_msg_queue queue;
|
struct sc_control_msg_queue queue;
|
||||||
struct sc_receiver receiver;
|
struct sc_receiver receiver;
|
||||||
|
|
||||||
|
const struct sc_controller_callbacks *cbs;
|
||||||
|
void *cbs_userdata;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sc_controller_callbacks {
|
||||||
|
void (*on_error)(struct sc_controller *controller, void *userdata);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sc_controller_init(struct sc_controller *controller, sc_socket control_socket);
|
sc_controller_init(struct sc_controller *controller, sc_socket control_socket,
|
||||||
|
const struct sc_controller_callbacks *cbs,
|
||||||
|
void *cbs_userdata);
|
||||||
|
|
||||||
void
|
void
|
||||||
sc_controller_configure(struct sc_controller *controller,
|
sc_controller_configure(struct sc_controller *controller,
|
||||||
|
@ -7,3 +7,4 @@
|
|||||||
#define SC_EVENT_RECORDER_ERROR (SDL_USEREVENT + 6)
|
#define SC_EVENT_RECORDER_ERROR (SDL_USEREVENT + 6)
|
||||||
#define SC_EVENT_SCREEN_INIT_SIZE (SDL_USEREVENT + 7)
|
#define SC_EVENT_SCREEN_INIT_SIZE (SDL_USEREVENT + 7)
|
||||||
#define SC_EVENT_TIME_LIMIT_REACHED (SDL_USEREVENT + 8)
|
#define SC_EVENT_TIME_LIMIT_REACHED (SDL_USEREVENT + 8)
|
||||||
|
#define SC_EVENT_CONTROLLER_ERROR (SDL_USEREVENT + 9)
|
||||||
|
@ -10,7 +10,8 @@
|
|||||||
#include "util/str.h"
|
#include "util/str.h"
|
||||||
|
|
||||||
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) {
|
||||||
bool ok = sc_mutex_init(&receiver->mutex);
|
bool ok = sc_mutex_init(&receiver->mutex);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
return false;
|
return false;
|
||||||
@ -20,6 +21,10 @@ sc_receiver_init(struct sc_receiver *receiver, sc_socket control_socket) {
|
|||||||
receiver->acksync = NULL;
|
receiver->acksync = NULL;
|
||||||
receiver->uhid_devices = NULL;
|
receiver->uhid_devices = NULL;
|
||||||
|
|
||||||
|
assert(cbs && cbs->on_error);
|
||||||
|
receiver->cbs = cbs;
|
||||||
|
receiver->cbs_userdata = cbs_userdata;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,6 +157,8 @@ run_receiver(void *data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
receiver->cbs->on_error(receiver, receiver->cbs_userdata);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,10 +19,18 @@ struct sc_receiver {
|
|||||||
|
|
||||||
struct sc_acksync *acksync;
|
struct sc_acksync *acksync;
|
||||||
struct sc_uhid_devices *uhid_devices;
|
struct sc_uhid_devices *uhid_devices;
|
||||||
|
|
||||||
|
const struct sc_receiver_callbacks *cbs;
|
||||||
|
void *cbs_userdata;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sc_receiver_callbacks {
|
||||||
|
void (*on_error)(struct sc_receiver *receiver, void *userdata);
|
||||||
};
|
};
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
void
|
void
|
||||||
sc_receiver_destroy(struct sc_receiver *receiver);
|
sc_receiver_destroy(struct sc_receiver *receiver);
|
||||||
|
@ -174,6 +174,9 @@ event_loop(struct scrcpy *s) {
|
|||||||
case SC_EVENT_DEMUXER_ERROR:
|
case SC_EVENT_DEMUXER_ERROR:
|
||||||
LOGE("Demuxer error");
|
LOGE("Demuxer error");
|
||||||
return SCRCPY_EXIT_FAILURE;
|
return SCRCPY_EXIT_FAILURE;
|
||||||
|
case SC_EVENT_CONTROLLER_ERROR:
|
||||||
|
LOGE("Controller error");
|
||||||
|
return SCRCPY_EXIT_FAILURE;
|
||||||
case SC_EVENT_RECORDER_ERROR:
|
case SC_EVENT_RECORDER_ERROR:
|
||||||
LOGE("Recorder error");
|
LOGE("Recorder error");
|
||||||
return SCRCPY_EXIT_FAILURE;
|
return SCRCPY_EXIT_FAILURE;
|
||||||
@ -265,6 +268,16 @@ sc_audio_demuxer_on_ended(struct sc_demuxer *demuxer,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sc_controller_on_error(struct sc_controller *controller, void *userdata) {
|
||||||
|
// Note: this function may be called twice, once from the controller thread
|
||||||
|
// and once from the receiver thread
|
||||||
|
(void) controller;
|
||||||
|
(void) userdata;
|
||||||
|
|
||||||
|
PUSH_EVENT(SC_EVENT_CONTROLLER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sc_server_on_connection_failed(struct sc_server *server, void *userdata) {
|
sc_server_on_connection_failed(struct sc_server *server, void *userdata) {
|
||||||
(void) server;
|
(void) server;
|
||||||
@ -553,7 +566,12 @@ scrcpy(struct scrcpy_options *options) {
|
|||||||
struct sc_mouse_processor *mp = NULL;
|
struct sc_mouse_processor *mp = NULL;
|
||||||
|
|
||||||
if (options->control) {
|
if (options->control) {
|
||||||
if (!sc_controller_init(&s->controller, s->server.control_socket)) {
|
static const struct sc_controller_callbacks controller_cbs = {
|
||||||
|
.on_error = sc_controller_on_error,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!sc_controller_init(&s->controller, s->server.control_socket,
|
||||||
|
&controller_cbs, NULL)) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
controller_initialized = true;
|
controller_initialized = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user