From a9dd9f03743cb0b1f8694fabffe7a490b337c11e Mon Sep 17 00:00:00 2001 From: that Date: Thu, 23 Feb 2017 23:08:56 +0100 Subject: gui: preserve order of gui_print vs gui_msg - rename __gui_print to internal_gui_print (__* is reserved for compiler) - translate outstanding messages in internal_gui_print - add locking because background thread could print while we render - minor cleanup Change-Id: Ib687d2cfb4763ad08ad4d4b76daf5b129d61d2e2 --- gui/console.cpp | 81 +++++++++++++++++++++++++++++++++++---------------------- gui/objects.hpp | 2 ++ gui/pages.cpp | 9 +------ 3 files changed, 53 insertions(+), 39 deletions(-) (limited to 'gui') diff --git a/gui/console.cpp b/gui/console.cpp index b518e77dc..03628ec30 100644 --- a/gui/console.cpp +++ b/gui/console.cpp @@ -23,15 +23,9 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include #include -#include +#include #include @@ -47,15 +41,30 @@ extern "C" { #define GUI_CONSOLE_BUFFER_SIZE 512 -size_t last_message_count = 0; -std::vector gMessages; +static pthread_mutex_t console_lock; +static size_t last_message_count = 0; +static std::vector gMessages; + +static std::vector gConsole; +static std::vector gConsoleColor; +static FILE* ors_file = NULL; -std::vector gConsole; -std::vector gConsoleColor; -static FILE* ors_file; +struct InitMutex +{ + InitMutex() { pthread_mutex_init(&console_lock, NULL); } +} initMutex; -extern "C" void __gui_print(const char *color, char *buf) +static void internal_gui_print(const char *color, char *buf) { + // make sure to flush any outstanding messages first to preserve order of outputs + GUIConsole::Translate_Now(); + + fputs(buf, stdout); + if (ors_file) { + fprintf(ors_file, "%s", buf); + fflush(ors_file); + } + char *start, *next; if (buf[0] == '\n' && strlen(buf) < 2) { @@ -63,6 +72,7 @@ extern "C" void __gui_print(const char *color, char *buf) return; } + pthread_mutex_lock(&console_lock); for (start = next = buf; *next != '\0';) { if (*next == '\n') @@ -82,6 +92,7 @@ extern "C" void __gui_print(const char *color, char *buf) gConsole.push_back(start); gConsoleColor.push_back(color); } + pthread_mutex_unlock(&console_lock); } extern "C" void gui_print(const char *fmt, ...) @@ -93,14 +104,7 @@ extern "C" void gui_print(const char *fmt, ...) vsnprintf(buf, GUI_CONSOLE_BUFFER_SIZE, fmt, ap); va_end(ap); - fputs(buf, stdout); - if (ors_file) { - fprintf(ors_file, "%s", buf); - fflush(ors_file); - } - - __gui_print("normal", buf); - return; + internal_gui_print("normal", buf); } extern "C" void gui_print_color(const char *color, const char *fmt, ...) @@ -112,14 +116,7 @@ extern "C" void gui_print_color(const char *color, const char *fmt, ...) vsnprintf(buf, GUI_CONSOLE_BUFFER_SIZE, fmt, ap); va_end(ap); - fputs(buf, stdout); - if (ors_file) { - fprintf(ors_file, "%s", buf); - fflush(ors_file); - } - - __gui_print(color, buf); - return; + internal_gui_print(color, buf); } extern "C" void gui_set_FILE(FILE* f) @@ -168,13 +165,20 @@ void gui_msg(Message msg) fprintf(ors_file, "%s", output.c_str()); fflush(ors_file); } + pthread_mutex_lock(&console_lock); gMessages.push_back(msg); + pthread_mutex_unlock(&console_lock); } -void GUIConsole::Translate_Now() { +void GUIConsole::Translate_Now() +{ + pthread_mutex_lock(&console_lock); size_t message_count = gMessages.size(); if (message_count <= last_message_count) + { + pthread_mutex_unlock(&console_lock); return; + } for (size_t m = last_message_count; m < message_count; m++) { std::string message = gMessages[m]; @@ -189,6 +193,16 @@ void GUIConsole::Translate_Now() { gConsoleColor.push_back(color); } last_message_count = message_count; + pthread_mutex_unlock(&console_lock); +} + +void GUIConsole::Clear_For_Retranslation() +{ + pthread_mutex_lock(&console_lock); + last_message_count = 0; + gConsole.clear(); + gConsoleColor.clear(); + pthread_mutex_unlock(&console_lock); } GUIConsole::GUIConsole(xml_node<>* node) : GUIScrollList(node) @@ -256,7 +270,9 @@ int GUIConsole::RenderSlideout(void) int GUIConsole::RenderConsole(void) { Translate_Now(); + pthread_mutex_lock(&console_lock); AddLines(&gConsole, &gConsoleColor, &mLastCount, &rConsole, &rConsoleColor); + pthread_mutex_unlock(&console_lock); GUIScrollList::Render(); // if last line is fully visible, keep tracking the last line when new lines are added @@ -307,7 +323,10 @@ int GUIConsole::Update(void) scrollToEnd = true; } - if (AddLines(&gConsole, &gConsoleColor, &mLastCount, &rConsole, &rConsoleColor)) { + pthread_mutex_lock(&console_lock); + bool addedNewText = AddLines(&gConsole, &gConsoleColor, &mLastCount, &rConsole, &rConsoleColor); + pthread_mutex_unlock(&console_lock); + if (addedNewText) { // someone added new text // at least the scrollbar must be updated, even if the new lines are currently not visible mUpdate = 1; diff --git a/gui/objects.hpp b/gui/objects.hpp index 28ed29cdb..630cf7102 100644 --- a/gui/objects.hpp +++ b/gui/objects.hpp @@ -746,7 +746,9 @@ public: virtual size_t GetItemCount(); virtual void RenderItem(size_t itemindex, int yPos, bool selected); virtual void NotifySelect(size_t item_selected); + static void Translate_Now(); + static void Clear_For_Retranslation(); protected: enum SlideoutState { diff --git a/gui/pages.cpp b/gui/pages.cpp index b2a978f4d..bf6c6921c 100644 --- a/gui/pages.cpp +++ b/gui/pages.cpp @@ -58,11 +58,6 @@ extern "C" { extern int gGuiRunning; -// From console.cpp -extern size_t last_message_count; -extern std::vector gConsole; -extern std::vector gConsoleColor; - std::map PageManager::mPageSets; PageSet* PageManager::mCurrentSet; MouseCursor *PageManager::mMouseCursor = NULL; @@ -1541,9 +1536,7 @@ int PageManager::RunReload() { } // This makes the console re-translate - last_message_count = 0; - gConsole.clear(); - gConsoleColor.clear(); + GUIConsole::Clear_For_Retranslation(); return ret_val; } -- cgit v1.2.3