diff --git a/sortix/logterminal.cpp b/sortix/logterminal.cpp index 30cf7576..7a61dae8 100644 --- a/sortix/logterminal.cpp +++ b/sortix/logterminal.cpp @@ -1,6 +1,6 @@ -/****************************************************************************** +/******************************************************************************* - COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012. + Copyright(C) Jonas 'Sortie' Termansen 2012. This file is part of Sortix. @@ -14,21 +14,21 @@ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with Sortix. If not, see . + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . logterminal.cpp A simple terminal that writes to the kernel log. -******************************************************************************/ +*******************************************************************************/ #include +#include #include #include #include "utf8.h" #include "keyboard.h" #include "scheduler.h" -#include #include "terminal.h" #include "logterminal.h" @@ -55,6 +55,10 @@ namespace Sortix | TERMMODE_UTF8 | TERMMODE_LINEBUFFER | TERMMODE_ECHO; + this->termlock = KTHREAD_MUTEX_INITIALIZER; + this->datacond = KTHREAD_COND_INITIALIZER; + this->numwaiting = 0; + this->numeofs = 0; keyboard->SetOwner(this, NULL); } @@ -66,6 +70,7 @@ namespace Sortix bool LogTerminal::SetMode(unsigned newmode) { + ScopedLock lock(&termlock); unsigned oldmode = mode; if ( oldmode & ~SUPPORTED_MODES ) { Error::Set(ENOSYS); return false; } bool oldutf8 = mode & TERMMODE_UTF8; @@ -79,18 +84,21 @@ namespace Sortix bool LogTerminal::SetWidth(unsigned width) { + ScopedLock lock(&termlock); if ( width != GetWidth() ) { Error::Set(ENOTSUP); return false; } return true; } bool LogTerminal::SetHeight(unsigned height) { + ScopedLock lock(&termlock); if ( height != GetHeight() ) { Error::Set(ENOTSUP); return false; } return true; } unsigned LogTerminal::GetMode() const { + ScopedLock lock(&termlock); return mode; } @@ -116,6 +124,8 @@ namespace Sortix { if ( !kbkey ) { return; } + ScopedLock lock(&termlock); + if ( kbkey == KBKEY_LCTRL ) { control = true; } if ( kbkey == -KBKEY_LCTRL ) { control = false; } if ( mode & TERMMODE_SIGNAL && control && kbkey == KBKEY_C ) @@ -123,6 +133,21 @@ namespace Sortix Scheduler::SigIntHack(); return; } + if ( mode & TERMMODE_SIGNAL && control && kbkey == KBKEY_D ) + { + if ( !linebuffer.CanPop() ) + { + numeofs++; +#ifdef GOT_ACTUAL_KTHREAD + if ( numwaiting ) + kthread_cond_broadcast(&datacond); +#else + queuecommitevent.Signal(); +#endif + } + return; + } + uint32_t unikbkey = KBKEY_ENCODE(kbkey); QueueUnicode(unikbkey); @@ -179,13 +204,40 @@ namespace Sortix void LogTerminal::CommitLineBuffer() { linebuffer.Commit(); +#ifdef GOT_ACTUAL_KTHREAD + if ( numwaiting ) + kthread_cond_broadcast(&datacond); +#else queuecommitevent.Signal(); +#endif } ssize_t LogTerminal::Read(byte* dest, size_t count) { + ScopedLockSignal lock(&termlock); + if ( !lock.IsAcquired() ) { Error::Set(EINTR); return -1; } size_t sofar = 0; size_t left = count; +#ifdef GOT_ACTUAL_KTHREAD + bool blocking = !(mode & TERMMODE_NONBLOCK); + while ( left && !linebuffer.CanPop() && blocking && !numeofs ) + { + numwaiting++; + bool abort = !kthread_cond_wait_signal(&datacond, &termlock); + numwaiting--; + if ( abort ) { Error::Set(EINTR); return -1; } + } + if ( left && !linebuffer.CanPop() && !blocking && !numeofs ) + { + Error::Set(EWOULDBLOCK); + return -1; + } +#endif + if ( numeofs ) + { + numeofs--; + return 0; + } while ( left && linebuffer.CanPop() ) { uint32_t codepoint = linebuffer.Peek(); @@ -238,6 +290,7 @@ namespace Sortix if ( !partiallywritten ) { linebuffer.Pop(); } } +#ifdef GOT_FAKE_KTHREAD // Block if no data were ready. if ( !sofar ) { @@ -245,6 +298,7 @@ namespace Sortix else { queuecommitevent.Register(); Error::Set(EBLOCKING); } return -1; } +#endif return sofar; } diff --git a/sortix/logterminal.h b/sortix/logterminal.h index c2076e30..74147dfe 100644 --- a/sortix/logterminal.h +++ b/sortix/logterminal.h @@ -1,6 +1,6 @@ -/****************************************************************************** +/******************************************************************************* - COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012. + Copyright(C) Jonas 'Sortie' Termansen 2012. This file is part of Sortix. @@ -14,18 +14,22 @@ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with Sortix. If not, see . + You should have received a copy of the GNU General Public License along with + Sortix. If not, see . + logterminal.h A simple terminal that writes to the kernel log. -******************************************************************************/ +*******************************************************************************/ #ifndef SORTIX_LOGTERMINAL_H #define SORTIX_LOGTERMINAL_H +#include +#ifdef GOT_FAKE_KTHREAD #include "event.h" +#endif #include "stream.h" #include "terminal.h" #include "keyboard.h" @@ -62,10 +66,16 @@ namespace Sortix void CommitLineBuffer(); private: + mutable kthread_mutex_t termlock; + kthread_cond_t datacond; + size_t numwaiting; + size_t numeofs; Keyboard* keyboard; KeyboardLayout* kblayout; LineBuffer linebuffer; +#ifdef GOT_FAKE_KTHREAD Event queuecommitevent; +#endif size_t partiallywritten; unsigned mode; bool control;