Thread secured logterminal class and implemented VEOF.

This commit is contained in:
Jonas 'Sortie' Termansen 2012-08-01 21:40:14 +02:00
parent bf07674d7a
commit 66d7234ab1
2 changed files with 75 additions and 11 deletions

View File

@ -1,6 +1,6 @@
/****************************************************************************** /*******************************************************************************
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012. Copyright(C) Jonas 'Sortie' Termansen 2012.
This file is part of Sortix. This file is part of Sortix.
@ -14,21 +14,21 @@
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details. details.
You should have received a copy of the GNU General Public License along You should have received a copy of the GNU General Public License along with
with Sortix. If not, see <http://www.gnu.org/licenses/>. Sortix. If not, see <http://www.gnu.org/licenses/>.
logterminal.cpp logterminal.cpp
A simple terminal that writes to the kernel log. A simple terminal that writes to the kernel log.
******************************************************************************/ *******************************************************************************/
#include <sortix/kernel/platform.h> #include <sortix/kernel/platform.h>
#include <sortix/keycodes.h>
#include <libmaxsi/error.h> #include <libmaxsi/error.h>
#include <libmaxsi/memory.h> #include <libmaxsi/memory.h>
#include "utf8.h" #include "utf8.h"
#include "keyboard.h" #include "keyboard.h"
#include "scheduler.h" #include "scheduler.h"
#include <sortix/keycodes.h>
#include "terminal.h" #include "terminal.h"
#include "logterminal.h" #include "logterminal.h"
@ -55,6 +55,10 @@ namespace Sortix
| TERMMODE_UTF8 | TERMMODE_UTF8
| TERMMODE_LINEBUFFER | TERMMODE_LINEBUFFER
| TERMMODE_ECHO; | TERMMODE_ECHO;
this->termlock = KTHREAD_MUTEX_INITIALIZER;
this->datacond = KTHREAD_COND_INITIALIZER;
this->numwaiting = 0;
this->numeofs = 0;
keyboard->SetOwner(this, NULL); keyboard->SetOwner(this, NULL);
} }
@ -66,6 +70,7 @@ namespace Sortix
bool LogTerminal::SetMode(unsigned newmode) bool LogTerminal::SetMode(unsigned newmode)
{ {
ScopedLock lock(&termlock);
unsigned oldmode = mode; unsigned oldmode = mode;
if ( oldmode & ~SUPPORTED_MODES ) { Error::Set(ENOSYS); return false; } if ( oldmode & ~SUPPORTED_MODES ) { Error::Set(ENOSYS); return false; }
bool oldutf8 = mode & TERMMODE_UTF8; bool oldutf8 = mode & TERMMODE_UTF8;
@ -79,18 +84,21 @@ namespace Sortix
bool LogTerminal::SetWidth(unsigned width) bool LogTerminal::SetWidth(unsigned width)
{ {
ScopedLock lock(&termlock);
if ( width != GetWidth() ) { Error::Set(ENOTSUP); return false; } if ( width != GetWidth() ) { Error::Set(ENOTSUP); return false; }
return true; return true;
} }
bool LogTerminal::SetHeight(unsigned height) bool LogTerminal::SetHeight(unsigned height)
{ {
ScopedLock lock(&termlock);
if ( height != GetHeight() ) { Error::Set(ENOTSUP); return false; } if ( height != GetHeight() ) { Error::Set(ENOTSUP); return false; }
return true; return true;
} }
unsigned LogTerminal::GetMode() const unsigned LogTerminal::GetMode() const
{ {
ScopedLock lock(&termlock);
return mode; return mode;
} }
@ -116,6 +124,8 @@ namespace Sortix
{ {
if ( !kbkey ) { return; } if ( !kbkey ) { return; }
ScopedLock lock(&termlock);
if ( kbkey == KBKEY_LCTRL ) { control = true; } if ( kbkey == KBKEY_LCTRL ) { control = true; }
if ( kbkey == -KBKEY_LCTRL ) { control = false; } if ( kbkey == -KBKEY_LCTRL ) { control = false; }
if ( mode & TERMMODE_SIGNAL && control && kbkey == KBKEY_C ) if ( mode & TERMMODE_SIGNAL && control && kbkey == KBKEY_C )
@ -123,6 +133,21 @@ namespace Sortix
Scheduler::SigIntHack(); Scheduler::SigIntHack();
return; 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); uint32_t unikbkey = KBKEY_ENCODE(kbkey);
QueueUnicode(unikbkey); QueueUnicode(unikbkey);
@ -179,13 +204,40 @@ namespace Sortix
void LogTerminal::CommitLineBuffer() void LogTerminal::CommitLineBuffer()
{ {
linebuffer.Commit(); linebuffer.Commit();
#ifdef GOT_ACTUAL_KTHREAD
if ( numwaiting )
kthread_cond_broadcast(&datacond);
#else
queuecommitevent.Signal(); queuecommitevent.Signal();
#endif
} }
ssize_t LogTerminal::Read(byte* dest, size_t count) 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 sofar = 0;
size_t left = count; 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() ) while ( left && linebuffer.CanPop() )
{ {
uint32_t codepoint = linebuffer.Peek(); uint32_t codepoint = linebuffer.Peek();
@ -238,6 +290,7 @@ namespace Sortix
if ( !partiallywritten ) { linebuffer.Pop(); } if ( !partiallywritten ) { linebuffer.Pop(); }
} }
#ifdef GOT_FAKE_KTHREAD
// Block if no data were ready. // Block if no data were ready.
if ( !sofar ) if ( !sofar )
{ {
@ -245,6 +298,7 @@ namespace Sortix
else { queuecommitevent.Register(); Error::Set(EBLOCKING); } else { queuecommitevent.Register(); Error::Set(EBLOCKING); }
return -1; return -1;
} }
#endif
return sofar; return sofar;
} }

View File

@ -1,6 +1,6 @@
/****************************************************************************** /*******************************************************************************
COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2012. Copyright(C) Jonas 'Sortie' Termansen 2012.
This file is part of Sortix. This file is part of Sortix.
@ -14,18 +14,22 @@
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details. details.
You should have received a copy of the GNU General Public License along You should have received a copy of the GNU General Public License along with
with Sortix. If not, see <http://www.gnu.org/licenses/>. Sortix. If not, see <http://www.gnu.org/licenses/>.
logterminal.h logterminal.h
A simple terminal that writes to the kernel log. A simple terminal that writes to the kernel log.
******************************************************************************/ *******************************************************************************/
#ifndef SORTIX_LOGTERMINAL_H #ifndef SORTIX_LOGTERMINAL_H
#define SORTIX_LOGTERMINAL_H #define SORTIX_LOGTERMINAL_H
#include <sortix/kernel/kthread.h>
#ifdef GOT_FAKE_KTHREAD
#include "event.h" #include "event.h"
#endif
#include "stream.h" #include "stream.h"
#include "terminal.h" #include "terminal.h"
#include "keyboard.h" #include "keyboard.h"
@ -62,10 +66,16 @@ namespace Sortix
void CommitLineBuffer(); void CommitLineBuffer();
private: private:
mutable kthread_mutex_t termlock;
kthread_cond_t datacond;
size_t numwaiting;
size_t numeofs;
Keyboard* keyboard; Keyboard* keyboard;
KeyboardLayout* kblayout; KeyboardLayout* kblayout;
LineBuffer linebuffer; LineBuffer linebuffer;
#ifdef GOT_FAKE_KTHREAD
Event queuecommitevent; Event queuecommitevent;
#endif
size_t partiallywritten; size_t partiallywritten;
unsigned mode; unsigned mode;
bool control; bool control;