Skip to content

Commit

Permalink
Terminate on controller error
Browse files Browse the repository at this point in the history
This is particularly important to react to server socket disconnection
since video and audio may be disabled.

PR #4868 <#4868>
  • Loading branch information
rom1v committed May 11, 2024
1 parent b5ed834 commit c875465
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 6 deletions.
26 changes: 24 additions & 2 deletions app/src/controller.c
Expand Up @@ -6,16 +6,32 @@

#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
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);

bool ok = sc_vecdeque_reserve(&controller->queue, SC_CONTROL_MSG_QUEUE_MAX);
if (!ok) {
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) {
sc_vecdeque_destroy(&controller->queue);
return false;
Expand All @@ -39,6 +55,10 @@ sc_controller_init(struct sc_controller *controller, sc_socket control_socket) {
controller->control_socket = control_socket;
controller->stopped = false;

assert(cbs && cbs->on_error);
controller->cbs = cbs;
controller->cbs_userdata = cbs_userdata;

return true;
}

Expand Down Expand Up @@ -127,6 +147,8 @@ run_controller(void *data) {
LOGD("Could not write msg to socket");
break;
}

controller->cbs->on_error(controller, controller->cbs_userdata);
}
return 0;
}
Expand Down
11 changes: 10 additions & 1 deletion app/src/controller.h
Expand Up @@ -22,10 +22,19 @@ struct sc_controller {
bool stopped;
struct sc_control_msg_queue queue;
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
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
sc_controller_configure(struct sc_controller *controller,
Expand Down
1 change: 1 addition & 0 deletions app/src/events.h
Expand Up @@ -7,3 +7,4 @@
#define SC_EVENT_RECORDER_ERROR (SDL_USEREVENT + 6)
#define SC_EVENT_SCREEN_INIT_SIZE (SDL_USEREVENT + 7)
#define SC_EVENT_TIME_LIMIT_REACHED (SDL_USEREVENT + 8)
#define SC_EVENT_CONTROLLER_ERROR (SDL_USEREVENT + 9)
9 changes: 8 additions & 1 deletion app/src/receiver.c
Expand Up @@ -10,7 +10,8 @@
#include "util/str.h"

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);
if (!ok) {
return false;
Expand All @@ -20,6 +21,10 @@ sc_receiver_init(struct sc_receiver *receiver, sc_socket control_socket) {
receiver->acksync = NULL;
receiver->uhid_devices = NULL;

assert(cbs && cbs->on_error);
receiver->cbs = cbs;
receiver->cbs_userdata = cbs_userdata;

return true;
}

Expand Down Expand Up @@ -152,6 +157,8 @@ run_receiver(void *data) {
}
}

receiver->cbs->on_error(receiver, receiver->cbs_userdata);

return 0;
}

Expand Down
10 changes: 9 additions & 1 deletion app/src/receiver.h
Expand Up @@ -19,10 +19,18 @@ struct sc_receiver {

struct sc_acksync *acksync;
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
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
sc_receiver_destroy(struct sc_receiver *receiver);
Expand Down
20 changes: 19 additions & 1 deletion app/src/scrcpy.c
Expand Up @@ -174,6 +174,9 @@ event_loop(struct scrcpy *s) {
case SC_EVENT_DEMUXER_ERROR:
LOGE("Demuxer error");
return SCRCPY_EXIT_FAILURE;
case SC_EVENT_CONTROLLER_ERROR:
LOGE("Controller error");
return SCRCPY_EXIT_FAILURE;
case SC_EVENT_RECORDER_ERROR:
LOGE("Recorder error");
return SCRCPY_EXIT_FAILURE;
Expand Down Expand Up @@ -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
sc_server_on_connection_failed(struct sc_server *server, void *userdata) {
(void) server;
Expand Down Expand Up @@ -553,7 +566,12 @@ scrcpy(struct scrcpy_options *options) {
struct sc_mouse_processor *mp = NULL;

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;
}
controller_initialized = true;
Expand Down

0 comments on commit c875465

Please sign in to comment.