Simplify cleanup
The cleanup is not linear: for example, the server must be stopped and its sockets must be shutdown after the stream and controller are stopped (so that they don't continue processing garbage), but before they are joined, to avoid a deadlock if they are blocked on a socket read. Simplify the spaghetti-cleanup by keeping trace of initialization at runtime.
This commit is contained in:
parent
0dee9b04b2
commit
bfb86ca2c2
1 changed files with 54 additions and 45 deletions
|
@ -280,20 +280,24 @@ scrcpy(const struct scrcpy_options *options) {
|
||||||
show_touches_waited = false;
|
show_touches_waited = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ret = true;
|
bool ret = false;
|
||||||
|
|
||||||
|
bool video_buffer_initialized = false;
|
||||||
|
bool file_handler_initialized = false;
|
||||||
|
bool recorder_initialized = false;
|
||||||
|
bool stream_started = false;
|
||||||
|
bool controller_initialized = false;
|
||||||
|
bool controller_started = false;
|
||||||
|
|
||||||
bool display = !options->no_display;
|
bool display = !options->no_display;
|
||||||
bool control = !options->no_control;
|
bool control = !options->no_control;
|
||||||
|
|
||||||
if (!sdl_init_and_configure(display)) {
|
if (!sdl_init_and_configure(display)) {
|
||||||
ret = false;
|
goto end;
|
||||||
goto finally_destroy_server;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!server_connect_to(&server)) {
|
if (!server_connect_to(&server)) {
|
||||||
server_stop(&server);
|
goto end;
|
||||||
ret = false;
|
|
||||||
goto finally_destroy_server;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_t device_socket = server.device_socket;
|
socket_t device_socket = server.device_socket;
|
||||||
|
@ -305,23 +309,21 @@ scrcpy(const struct scrcpy_options *options) {
|
||||||
// change therefore, we transmit the screen size before the video stream,
|
// change therefore, we transmit the screen size before the video stream,
|
||||||
// to be able to init the window immediately
|
// to be able to init the window immediately
|
||||||
if (!device_read_info(device_socket, device_name, &frame_size)) {
|
if (!device_read_info(device_socket, device_name, &frame_size)) {
|
||||||
server_stop(&server);
|
goto end;
|
||||||
ret = false;
|
|
||||||
goto finally_destroy_server;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct decoder *dec = NULL;
|
struct decoder *dec = NULL;
|
||||||
if (display) {
|
if (display) {
|
||||||
if (!video_buffer_init(&video_buffer)) {
|
if (!video_buffer_init(&video_buffer)) {
|
||||||
server_stop(&server);
|
goto end;
|
||||||
ret = false;
|
|
||||||
goto finally_destroy_server;
|
|
||||||
}
|
}
|
||||||
|
video_buffer_initialized = true;
|
||||||
|
|
||||||
if (control && !file_handler_init(&file_handler, server.serial)) {
|
if (control) {
|
||||||
ret = false;
|
if (!file_handler_init(&file_handler, server.serial)) {
|
||||||
server_stop(&server);
|
goto end;
|
||||||
goto finally_destroy_video_buffer;
|
}
|
||||||
|
file_handler_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
decoder_init(&decoder, &video_buffer);
|
decoder_init(&decoder, &video_buffer);
|
||||||
|
@ -334,11 +336,10 @@ scrcpy(const struct scrcpy_options *options) {
|
||||||
options->record_filename,
|
options->record_filename,
|
||||||
options->record_format,
|
options->record_format,
|
||||||
frame_size)) {
|
frame_size)) {
|
||||||
ret = false;
|
goto end;
|
||||||
server_stop(&server);
|
|
||||||
goto finally_destroy_file_handler;
|
|
||||||
}
|
}
|
||||||
rec = &recorder;
|
rec = &recorder;
|
||||||
|
recorder_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
av_log_set_callback(av_log_callback);
|
av_log_set_callback(av_log_callback);
|
||||||
|
@ -348,28 +349,24 @@ scrcpy(const struct scrcpy_options *options) {
|
||||||
// now we consumed the header values, the socket receives the video stream
|
// now we consumed the header values, the socket receives the video stream
|
||||||
// start the stream
|
// start the stream
|
||||||
if (!stream_start(&stream)) {
|
if (!stream_start(&stream)) {
|
||||||
ret = false;
|
goto end;
|
||||||
server_stop(&server);
|
|
||||||
goto finally_destroy_recorder;
|
|
||||||
}
|
}
|
||||||
|
stream_started = true;
|
||||||
|
|
||||||
if (display) {
|
if (display) {
|
||||||
if (control) {
|
if (control) {
|
||||||
if (!controller_init(&controller, device_socket)) {
|
if (!controller_init(&controller, device_socket)) {
|
||||||
ret = false;
|
goto end;
|
||||||
goto finally_stop_stream;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!controller_start(&controller)) {
|
if (!controller_start(&controller)) {
|
||||||
ret = false;
|
goto end;
|
||||||
goto finally_destroy_controller;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!screen_init_rendering(&screen, device_name, frame_size,
|
if (!screen_init_rendering(&screen, device_name, frame_size,
|
||||||
options->always_on_top)) {
|
options->always_on_top)) {
|
||||||
ret = false;
|
goto end;
|
||||||
goto finally_stop_and_join_controller;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options->fullscreen) {
|
if (options->fullscreen) {
|
||||||
|
@ -387,35 +384,47 @@ scrcpy(const struct scrcpy_options *options) {
|
||||||
|
|
||||||
screen_destroy(&screen);
|
screen_destroy(&screen);
|
||||||
|
|
||||||
finally_stop_and_join_controller:
|
end:
|
||||||
if (display && control) {
|
// stop stream and controller so that they don't continue once their socket
|
||||||
|
// is shutdown
|
||||||
|
if (stream_started) {
|
||||||
|
stream_stop(&stream);
|
||||||
|
}
|
||||||
|
if (controller_started) {
|
||||||
controller_stop(&controller);
|
controller_stop(&controller);
|
||||||
|
}
|
||||||
|
if (file_handler_initialized) {
|
||||||
|
file_handler_stop(&file_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
// shutdown the sockets and kill the server
|
||||||
|
server_stop(&server);
|
||||||
|
|
||||||
|
// now that the sockets are shutdown, the stream and controller are
|
||||||
|
// interrupted, we can join them
|
||||||
|
if (stream_started) {
|
||||||
|
stream_join(&stream);
|
||||||
|
}
|
||||||
|
if (controller_started) {
|
||||||
controller_join(&controller);
|
controller_join(&controller);
|
||||||
}
|
}
|
||||||
finally_destroy_controller:
|
if (controller_initialized) {
|
||||||
if (display && control) {
|
|
||||||
controller_destroy(&controller);
|
controller_destroy(&controller);
|
||||||
}
|
}
|
||||||
finally_stop_stream:
|
|
||||||
stream_stop(&stream);
|
if (recorder_initialized) {
|
||||||
// stop the server before stream_join() to wake up the stream
|
|
||||||
server_stop(&server);
|
|
||||||
stream_join(&stream);
|
|
||||||
finally_destroy_recorder:
|
|
||||||
if (record) {
|
|
||||||
recorder_destroy(&recorder);
|
recorder_destroy(&recorder);
|
||||||
}
|
}
|
||||||
finally_destroy_file_handler:
|
|
||||||
if (display && control) {
|
if (file_handler_initialized) {
|
||||||
file_handler_stop(&file_handler);
|
|
||||||
file_handler_join(&file_handler);
|
file_handler_join(&file_handler);
|
||||||
file_handler_destroy(&file_handler);
|
file_handler_destroy(&file_handler);
|
||||||
}
|
}
|
||||||
finally_destroy_video_buffer:
|
|
||||||
if (display) {
|
if (video_buffer_initialized) {
|
||||||
video_buffer_destroy(&video_buffer);
|
video_buffer_destroy(&video_buffer);
|
||||||
}
|
}
|
||||||
finally_destroy_server:
|
|
||||||
if (options->show_touches) {
|
if (options->show_touches) {
|
||||||
if (!show_touches_waited) {
|
if (!show_touches_waited) {
|
||||||
// wait the process which enabled "show touches"
|
// wait the process which enabled "show touches"
|
||||||
|
|
Loading…
Reference in a new issue