From 5c13b547590dfcb98c66078c97c2bcb617c043bb Mon Sep 17 00:00:00 2001 From: Steven Smith Date: Sat, 30 Apr 2016 21:17:18 -0700 Subject: [PATCH] Fix freeze when waiting for tasks to exit, don't mistakenly require mutex to start camera capture task. --- source/ui/section/action/deletecontents.c | 2 + .../ui/section/action/deletependingtitles.c | 2 + source/ui/section/action/installcdn.c | 37 +------- source/ui/section/action/installcias.c | 2 + source/ui/section/action/installtickets.c | 2 + source/ui/section/action/pastefiles.c | 2 + source/ui/section/dumpnand.c | 2 + source/ui/section/networkinstall.c | 94 +++++++++++-------- source/ui/section/qrinstall.c | 78 ++++++++------- source/ui/section/task/capturecam.c | 5 +- source/ui/section/task/dataop.c | 2 + source/ui/section/task/listextsavedata.c | 2 + source/ui/section/task/listfiles.c | 2 + source/ui/section/task/listpendingtitles.c | 2 + source/ui/section/task/listsystemsavedata.c | 2 + source/ui/section/task/listtickets.c | 2 + source/ui/section/task/listtitles.c | 2 + 17 files changed, 131 insertions(+), 109 deletions(-) diff --git a/source/ui/section/action/deletecontents.c b/source/ui/section/action/deletecontents.c index 5d1fe72..d9d8506 100644 --- a/source/ui/section/action/deletecontents.c +++ b/source/ui/section/action/deletecontents.c @@ -166,6 +166,8 @@ static void action_delete_contents_internal(linked_list* items, list_item* selec data->deleteInfo.error = action_delete_contents_error; + data->deleteInfo.finished = false; + linked_list_init(&data->contents); populate_files_data popData; diff --git a/source/ui/section/action/deletependingtitles.c b/source/ui/section/action/deletependingtitles.c index bff0ad1..bf7805c 100644 --- a/source/ui/section/action/deletependingtitles.c +++ b/source/ui/section/action/deletependingtitles.c @@ -141,6 +141,8 @@ void action_delete_pending_titles(linked_list* items, list_item* selected, const data->deleteInfo.error = action_delete_pending_titles_error; + data->deleteInfo.finished = true; + linked_list_init(&data->contents); if(all) { diff --git a/source/ui/section/action/installcdn.c b/source/ui/section/action/installcdn.c index c8cb47d..0470e81 100644 --- a/source/ui/section/action/installcdn.c +++ b/source/ui/section/action/installcdn.c @@ -248,6 +248,8 @@ void action_install_cdn_noprompt(volatile bool* done, ticket_info* info, bool fi data->installInfo.error = action_install_cdn_error; + data->installInfo.finished = true; + Result res = 0; u8 n3ds = false; @@ -286,38 +288,5 @@ static void action_install_cdn_onresponse(ui_view* view, void* data, bool respon } void action_install_cdn(linked_list* items, list_item* selected) { - install_cdn_data* data = (install_cdn_data*) calloc(1, sizeof(install_cdn_data)); - if(data == NULL) { - error_display(NULL, NULL, NULL, "Failed to allocate install CDN data."); - - return; - } - - data->ticket = (ticket_info*) selected->data; - - data->responseCode = 0; - - data->installInfo.data = data; - - data->installInfo.op = DATAOP_COPY; - - data->installInfo.copyEmpty = false; - - data->installInfo.total = 1; - - data->installInfo.isSrcDirectory = action_install_cdn_is_src_directory; - data->installInfo.makeDstDirectory = action_install_cdn_make_dst_directory; - - data->installInfo.openSrc = action_install_cdn_open_src; - data->installInfo.closeSrc = action_install_cdn_close_src; - data->installInfo.getSrcSize = action_install_cdn_get_src_size; - data->installInfo.readSrc = action_install_cdn_read_src; - - data->installInfo.openDst = action_install_cdn_open_dst; - data->installInfo.closeDst = action_install_cdn_close_dst; - data->installInfo.writeDst = action_install_cdn_write_dst; - - data->installInfo.error = action_install_cdn_error; - - prompt_display("Confirmation", "Install the selected title from the CDN?", COLOR_TEXT, true, data, NULL, action_install_cdn_draw_top, action_install_cdn_onresponse); + prompt_display("Confirmation", "Install the selected title from the CDN?", COLOR_TEXT, true, selected->data, NULL, ui_draw_ticket_info, action_install_cdn_onresponse); } \ No newline at end of file diff --git a/source/ui/section/action/installcias.c b/source/ui/section/action/installcias.c index 327ee36..427edf2 100644 --- a/source/ui/section/action/installcias.c +++ b/source/ui/section/action/installcias.c @@ -275,6 +275,8 @@ static void action_install_cias_internal(linked_list* items, list_item* selected data->installInfo.error = action_install_cias_error; + data->installInfo.finished = true; + linked_list_init(&data->contents); populate_files_data popData; diff --git a/source/ui/section/action/installtickets.c b/source/ui/section/action/installtickets.c index d173cc0..6381a95 100644 --- a/source/ui/section/action/installtickets.c +++ b/source/ui/section/action/installtickets.c @@ -251,6 +251,8 @@ static void action_install_tickets_internal(linked_list* items, list_item* selec data->installInfo.error = action_install_tickets_error; + data->installInfo.finished = true; + linked_list_init(&data->contents); populate_files_data popData; diff --git a/source/ui/section/action/pastefiles.c b/source/ui/section/action/pastefiles.c index da855a4..42d3755 100644 --- a/source/ui/section/action/pastefiles.c +++ b/source/ui/section/action/pastefiles.c @@ -295,6 +295,8 @@ void action_paste_contents(linked_list* items, list_item* selected) { data->pasteInfo.error = action_paste_files_error; + data->pasteInfo.finished = true; + list_item* clipboardItem = NULL; Result createRes = 0; if(R_FAILED(createRes = task_create_file_item(&clipboardItem, clipboard_get_archive(), clipboard_get_path()))) { diff --git a/source/ui/section/dumpnand.c b/source/ui/section/dumpnand.c index 8cc3c23..c7adea8 100644 --- a/source/ui/section/dumpnand.c +++ b/source/ui/section/dumpnand.c @@ -127,5 +127,7 @@ void dumpnand_open() { data->error = dumpnand_error; + data->finished = true; + prompt_display("Confirmation", "Dump raw NAND image to the SD card?", COLOR_TEXT, true, data, NULL, NULL, dumpnand_onresponse); } \ No newline at end of file diff --git a/source/ui/section/networkinstall.c b/source/ui/section/networkinstall.c index ec84aa2..4a1f334 100644 --- a/source/ui/section/networkinstall.c +++ b/source/ui/section/networkinstall.c @@ -204,14 +204,28 @@ static bool networkinstall_error(void* data, u32 index, Result res) { } static void networkinstall_close_client(network_install_data* data) { - u8 ack = 0; - sendwait(data->clientSocket, &ack, sizeof(ack), 0); + if(data->clientSocket != 0) { + u8 ack = 0; + sendwait(data->clientSocket, &ack, sizeof(ack), 0); - close(data->clientSocket); + close(data->clientSocket); + data->clientSocket = 0; + } data->currTitleId = 0; } +static void networkinstall_free_data(network_install_data* data) { + networkinstall_close_client(data); + + if(data->serverSocket != 0) { + close(data->serverSocket); + data->serverSocket = 0; + } + + free(data); +} + static void networkinstall_install_update(ui_view* view, void* data, float* progress, char* text) { network_install_data* networkInstallData = (network_install_data*) data; @@ -266,8 +280,7 @@ static void networkinstall_wait_update(ui_view* view, void* data, float* progres ui_pop(); info_destroy(view); - close(networkInstallData->serverSocket); - free(networkInstallData); + networkinstall_free_data(networkInstallData); return; } @@ -304,41 +317,6 @@ void networkinstall_open() { return; } - int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); - if(sock < 0) { - error_display_errno(NULL, NULL, NULL, errno, "Failed to open server socket."); - - free(data); - return; - } - - int bufSize = 1024 * 32; - setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &bufSize, sizeof(bufSize)); - - struct sockaddr_in server; - server.sin_family = AF_INET; - server.sin_port = htons(5000); - server.sin_addr.s_addr = (in_addr_t) gethostid(); - - if(bind(sock, (struct sockaddr*) &server, sizeof(server)) < 0) { - error_display_errno(NULL, NULL, NULL, errno, "Failed to bind server socket."); - - close(sock); - free(data); - return; - } - - fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK); - - if(listen(sock, 5) < 0) { - error_display_errno(NULL, NULL, NULL, errno, "Failed to listen on server socket."); - - close(sock); - free(data); - return; - } - - data->serverSocket = sock; data->clientSocket = 0; data->currTitleId = 0; @@ -364,5 +342,41 @@ void networkinstall_open() { data->installInfo.error = networkinstall_error; + data->installInfo.finished = true; + + int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + if(sock < 0) { + error_display_errno(NULL, NULL, NULL, errno, "Failed to open server socket."); + + networkinstall_free_data(data); + return; + } + + data->serverSocket = sock; + + int bufSize = 1024 * 32; + setsockopt(data->serverSocket, SOL_SOCKET, SO_RCVBUF, &bufSize, sizeof(bufSize)); + + struct sockaddr_in server; + server.sin_family = AF_INET; + server.sin_port = htons(5000); + server.sin_addr.s_addr = (in_addr_t) gethostid(); + + if(bind(data->serverSocket, (struct sockaddr*) &server, sizeof(server)) < 0) { + error_display_errno(NULL, NULL, NULL, errno, "Failed to bind server socket."); + + networkinstall_free_data(data); + return; + } + + fcntl(data->serverSocket, F_SETFL, fcntl(data->serverSocket, F_GETFL, 0) | O_NONBLOCK); + + if(listen(data->serverSocket, 5) < 0) { + error_display_errno(NULL, NULL, NULL, errno, "Failed to listen on server socket."); + + networkinstall_free_data(data); + return; + } + info_display("Network Install", "B: Return", false, data, networkinstall_wait_update, NULL); } diff --git a/source/ui/section/qrinstall.c b/source/ui/section/qrinstall.c index 6a3c2d1..f4c12fc 100644 --- a/source/ui/section/qrinstall.c +++ b/source/ui/section/qrinstall.c @@ -272,6 +272,13 @@ static void qrinstall_free_data(qr_install_data* data) { } } + if(!data->captureInfo.finished) { + svcSignalEvent(data->captureInfo.cancelEvent); + while(!data->captureInfo.finished) { + svcSleepThread(1000000); + } + } + if(data->captureInfo.buffer != NULL) { free(data->captureInfo.buffer); data->captureInfo.buffer = NULL; @@ -390,39 +397,6 @@ void qrinstall_open() { return; } - data->qrContext = quirc_new(); - if(data->qrContext == NULL) { - error_display(NULL, NULL, NULL, "Failed to create QR context."); - - qrinstall_free_data(data); - return; - } - - if(quirc_resize(data->qrContext, IMAGE_WIDTH, IMAGE_HEIGHT) != 0) { - error_display(NULL, NULL, NULL, "Failed to resize QR context."); - - qrinstall_free_data(data); - return; - } - - data->captureInfo.width = IMAGE_WIDTH; - data->captureInfo.height = IMAGE_HEIGHT; - data->captureInfo.buffer = (u16*) calloc(1, IMAGE_WIDTH * IMAGE_HEIGHT * sizeof(u16)); - if(data->captureInfo.buffer == NULL) { - error_display(NULL, NULL, NULL, "Failed to create image buffer."); - - qrinstall_free_data(data); - return; - } - - Result capRes = task_capture_cam(&data->captureInfo); - if(R_FAILED(capRes)) { - error_display_res(NULL, NULL, NULL, capRes, "Failed to start camera capture."); - - qrinstall_free_data(data); - return; - } - data->tex = 0; data->responseCode = 0; @@ -451,5 +425,43 @@ void qrinstall_open() { data->installInfo.error = qrinstall_error; + data->installInfo.finished = true; + + data->captureInfo.width = IMAGE_WIDTH; + data->captureInfo.height = IMAGE_HEIGHT; + + data->captureInfo.finished = true; + + data->qrContext = quirc_new(); + if(data->qrContext == NULL) { + error_display(NULL, NULL, NULL, "Failed to create QR context."); + + qrinstall_free_data(data); + return; + } + + if(quirc_resize(data->qrContext, IMAGE_WIDTH, IMAGE_HEIGHT) != 0) { + error_display(NULL, NULL, NULL, "Failed to resize QR context."); + + qrinstall_free_data(data); + return; + } + + data->captureInfo.buffer = (u16*) calloc(1, IMAGE_WIDTH * IMAGE_HEIGHT * sizeof(u16)); + if(data->captureInfo.buffer == NULL) { + error_display(NULL, NULL, NULL, "Failed to create image buffer."); + + qrinstall_free_data(data); + return; + } + + Result capRes = task_capture_cam(&data->captureInfo); + if(R_FAILED(capRes)) { + error_display_res(NULL, NULL, NULL, capRes, "Failed to start camera capture."); + + qrinstall_free_data(data); + return; + } + info_display("QR Code Install", "B: Return", false, data, qrinstall_wait_update, qrinstall_wait_draw_top); } diff --git a/source/ui/section/task/capturecam.c b/source/ui/section/task/capturecam.c index 9421630..89fd173 100644 --- a/source/ui/section/task/capturecam.c +++ b/source/ui/section/task/capturecam.c @@ -113,11 +113,10 @@ static void task_capture_cam_thread(void* arg) { } Result task_capture_cam(capture_cam_data* data) { - if(data == NULL || data->buffer == NULL || data->width <= 0 || data->width > 640 || data->height <= 0 || data->height > 480 || data->mutex == 0) { + if(data == NULL || data->buffer == NULL || data->width <= 0 || data->width > 640 || data->height <= 0 || data->height > 480) { return R_FBI_INVALID_ARGUMENT; } - data->mutex = 0; data->finished = false; @@ -132,6 +131,8 @@ Result task_capture_cam(capture_cam_data* data) { } if(R_FAILED(res)) { + data->finished = true; + if(data->cancelEvent != 0) { svcCloseHandle(data->cancelEvent); data->cancelEvent = 0; diff --git a/source/ui/section/task/dataop.c b/source/ui/section/task/dataop.c index 5a4a921..dbaff43 100644 --- a/source/ui/section/task/dataop.c +++ b/source/ui/section/task/dataop.c @@ -154,6 +154,8 @@ Result task_data_op(data_op_data* data) { } if(R_FAILED(res)) { + data->finished = true; + if(data->cancelEvent != 0) { svcCloseHandle(data->cancelEvent); data->cancelEvent = 0; diff --git a/source/ui/section/task/listextsavedata.c b/source/ui/section/task/listextsavedata.c index bc4f251..cf59d2d 100644 --- a/source/ui/section/task/listextsavedata.c +++ b/source/ui/section/task/listextsavedata.c @@ -175,6 +175,8 @@ Result task_populate_ext_save_data(populate_ext_save_data_data* data) { } if(R_FAILED(res)) { + data->finished = true; + if(data->cancelEvent != 0) { svcCloseHandle(data->cancelEvent); data->cancelEvent = 0; diff --git a/source/ui/section/task/listfiles.c b/source/ui/section/task/listfiles.c index 8c6a868..e81288c 100644 --- a/source/ui/section/task/listfiles.c +++ b/source/ui/section/task/listfiles.c @@ -298,6 +298,8 @@ Result task_populate_files(populate_files_data* data) { } if(R_FAILED(res)) { + data->finished = true; + if(data->cancelEvent != 0) { svcCloseHandle(data->cancelEvent); data->cancelEvent = 0; diff --git a/source/ui/section/task/listpendingtitles.c b/source/ui/section/task/listpendingtitles.c index ac21571..4ff74be 100644 --- a/source/ui/section/task/listpendingtitles.c +++ b/source/ui/section/task/listpendingtitles.c @@ -142,6 +142,8 @@ Result task_populate_pending_titles(populate_pending_titles_data* data) { } if(R_FAILED(res)) { + data->finished = true; + if(data->cancelEvent != 0) { svcCloseHandle(data->cancelEvent); data->cancelEvent = 0; diff --git a/source/ui/section/task/listsystemsavedata.c b/source/ui/section/task/listsystemsavedata.c index 0af52ca..facab85 100644 --- a/source/ui/section/task/listsystemsavedata.c +++ b/source/ui/section/task/listsystemsavedata.c @@ -110,6 +110,8 @@ Result task_populate_system_save_data(populate_system_save_data_data* data) { } if(R_FAILED(res)) { + data->finished = true; + if(data->cancelEvent != 0) { svcCloseHandle(data->cancelEvent); data->cancelEvent = 0; diff --git a/source/ui/section/task/listtickets.c b/source/ui/section/task/listtickets.c index fbcc602..148101a 100644 --- a/source/ui/section/task/listtickets.c +++ b/source/ui/section/task/listtickets.c @@ -116,6 +116,8 @@ Result task_populate_tickets(populate_tickets_data* data) { } if(R_FAILED(res)) { + data->finished = true; + if(data->cancelEvent != 0) { svcCloseHandle(data->cancelEvent); data->cancelEvent = 0; diff --git a/source/ui/section/task/listtitles.c b/source/ui/section/task/listtitles.c index 5392f2a..09258cd 100644 --- a/source/ui/section/task/listtitles.c +++ b/source/ui/section/task/listtitles.c @@ -364,6 +364,8 @@ Result task_populate_titles(populate_titles_data* data) { } if(R_FAILED(res)) { + data->finished = true; + if(data->cancelEvent != 0) { svcCloseHandle(data->cancelEvent); data->cancelEvent = 0;