diff --git a/dispd/client/session.cpp b/dispd/client/session.cpp index 5b6d0024..32581806 100644 --- a/dispd/client/session.cpp +++ b/dispd/client/session.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -121,5 +122,19 @@ bool dispd_session_setup_game_rgba(struct dispd_session* session) perror(chvideomode); exit(127); } + + // TODO: HACK: The console may be rendered asynchronously and it is still + // rendering to the framebuffer, but this process may be able to write to + // the framebuffer before it is done. We need to wait for the console to + // finish to fix this race condition. + int ttyfd = open("/dev/tty", O_WRONLY); + if ( 0 <= ttyfd ) + { + // TODO: There is no fsync system call yet! Whoops! However, closing a + // file descriptor also happens to sync it, so this actually works. + //fsync(ttyfd); + close(ttyfd); + } + return session->is_rgba = true; } diff --git a/sortix/include/sortix/kernel/log.h b/sortix/include/sortix/kernel/log.h index f7ca4a91..0a1ea898 100644 --- a/sortix/include/sortix/kernel/log.h +++ b/sortix/include/sortix/kernel/log.h @@ -35,11 +35,13 @@ namespace Sortix extern size_t (*deviceCallback)(void*, const char*, size_t); extern size_t (*deviceWidth)(void*); extern size_t (*deviceHeight)(void*); + extern bool (*deviceSync)(void*); extern void* devicePointer; void Init(size_t (*callback)(void*, const char*, size_t), size_t (*widthfunc)(void*), size_t (*heightfunc)(void*), + bool (*syncfunc)(void*), void* user); inline void Flush() @@ -57,6 +59,11 @@ namespace Sortix return deviceHeight(devicePointer); } + inline bool Sync() + { + return deviceSync(devicePointer); + } + inline size_t Print(const char* str) { if ( !deviceCallback ) { return 0; } diff --git a/sortix/kernel.cpp b/sortix/kernel.cpp index 1d03d3a0..d5151c7a 100644 --- a/sortix/kernel.cpp +++ b/sortix/kernel.cpp @@ -135,6 +135,11 @@ static size_t TextTermHeight(void* user) return ((TextTerminal*) user)->Height(); } +static bool TextTermSync(void* user) +{ + return ((TextTerminal*) user)->Sync(); +} + addr_t initrd; size_t initrdsize; Ref textbufhandle; @@ -166,7 +171,8 @@ extern "C" void KernelInit(unsigned long magic, multiboot_info_t* bootinfo) TextTerminal textterm(textbufhandle); // Register the text terminal as the kernel log and initialize it. - Log::Init(PrintToTextTerminal, TextTermWidth, TextTermHeight, &textterm); + Log::Init(PrintToTextTerminal, TextTermWidth, TextTermHeight, TextTermSync, + &textterm); // Display the boot welcome screen. DoWelcome(); diff --git a/sortix/log.cpp b/sortix/log.cpp index d6a92ba9..83898b55 100644 --- a/sortix/log.cpp +++ b/sortix/log.cpp @@ -35,6 +35,7 @@ namespace Sortix size_t (*deviceCallback)(void*, const char*, size_t) = NULL; size_t (*deviceWidth)(void*) = NULL; size_t (*deviceHeight)(void*) = NULL; + bool (*deviceSync)(void*) = NULL; void* devicePointer = NULL; size_t SysPrintString(const char* str) @@ -47,11 +48,13 @@ namespace Sortix void Init(size_t (*callback)(void*, const char*, size_t), size_t (*widthfunc)(void*), size_t (*heightfunc)(void*), + bool (*syncfunc)(void*), void* user) { deviceCallback = callback; deviceWidth = widthfunc; deviceHeight = heightfunc; + deviceSync = syncfunc; devicePointer = user; Syscall::Register(SYSCALL_PRINT_STRING, (void*) SysPrintString); diff --git a/sortix/logterminal.cpp b/sortix/logterminal.cpp index 8eb12b14..5c40777e 100644 --- a/sortix/logterminal.cpp +++ b/sortix/logterminal.cpp @@ -125,7 +125,7 @@ int LogTerminal::tcgetwinsize(ioctx_t* ctx, struct winsize* ws) int LogTerminal::sync(ioctx_t* /*ctx*/) { - return 0; // Not needed. + return Log::Sync() ? 0 : -1; } void LogTerminal::OnKeystroke(Keyboard* kb, void* /*user*/) diff --git a/sortix/textterminal.cpp b/sortix/textterminal.cpp index 2d6128d8..2a642b5d 100644 --- a/sortix/textterminal.cpp +++ b/sortix/textterminal.cpp @@ -89,6 +89,17 @@ size_t TextTerminal::Height() const return height; } +bool TextTerminal::Sync() +{ + // Reading something from the textbuffer may cause it to block while + // finishing rendering, effectively synchronizing with it. + ScopedLock lock(&termlock); + TextBuffer* textbuf = textbufhandle->Acquire(); + textbuf->GetCursorPos(); + textbufhandle->Release(textbuf); + return true; +} + void TextTerminal::PutChar(TextBuffer* textbuf, char c) { if ( ansimode ) diff --git a/sortix/textterminal.h b/sortix/textterminal.h index 30c66cee..2990dadb 100644 --- a/sortix/textterminal.h +++ b/sortix/textterminal.h @@ -40,6 +40,7 @@ public: size_t Print(const char* string, size_t stringlen); size_t Width() const; size_t Height() const; + bool Sync(); private: void PutChar(TextBuffer* textbuf, char c);