bug-ncurses
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Is a "silent" ncurses initialization possible?


From: Robin Haberkorn
Subject: Re: Is a "silent" ncurses initialization possible?
Date: Mon, 8 Jun 2015 19:12:08 +0200
User-agent: Mutt/1.5.21 (2010-09-15)

On Mon, Jun 08, 2015 at 05:10:29AM -0400, Thomas Dickey wrote:
> On Thu, Jun 04, 2015 at 03:24:00PM +0200, Robin Haberkorn wrote:
> > 
> > screen = newterm(NULL, screen_tty, screen_tty);
> 
> This is the problem: "/dev/null" is not a tty device, so the system
> calls which rely upon that will fail.  ncurses allows this (rather than
> refusing to open it in newterm), but returns the error status from the various
> functions (such as cbreak).
>
Of course it is not a tty-device. But later on, I freopen() `screen_tty`
with the tty-device.
Why does cbreak() still fail then?

Nevertheless, I think I'll just extend Scinterm in the manner described
to get it working before initializing ncurses (or any curses) via initscr().

Btw. I do know it's possible to open /dev/tty with newterm() in the first
place. I used to do it in SciTECO as well. This will leave stdin/stdout
alone and allows for redirections. However I wasn't satisfied with
this solution either because of the remaining terminal interaction
that resulted in screen flickering at startup and problems when executing
SciTECO as a sub-process from other curses applications that do not
expect terminal interaction.
 
> > I would also like to avoid relying on SIGINT delivery for
> > interruptions by splitting
> > the input loop in two threads: One with a wgetch() or getch() loop and
> > the other one for executing
> > SciTECO macros and doing all the remaining Curses work.
> > Is it safe - with a non-threading ncurses build - to do that?
> 
> no - you would have to do _all_ of the ncurses work in one thread.
>
I expected something like this :-(.

The problem is: It's often not that easy. I have synchronous operations
involving ncurses - doing them all in one thread (i.e. the UI thread)
introduces a massive performance penalty due to synchronization and
copying. But I'd have to see; the performance decrease might be
smaller than anticipated since I also have a lot of operations that
could be made asynchronous (i.e. the non-UI thread does not always have
to wait for an answer).

But what's worse: Even then, I don't think it will work.
How can the "worker" (non-UI) thread get the UI thread that is blocking
on getch() to wake up and perform additional ncurses operations???
AFAIK and according to getch(3NCURSES) there is no way to interrupt
getch() via signals and no thread-safe function for inserting messages
into the input FIFO that could be abused for turning getch() into
an event loop. As long as the UI thread is blocking, it appears
there is no way to safely call other curses functions.

Furthermore, ncurses (not to mention XOpen/curses) does not provide any
way to separate its I/O from key processing which could be used
to integrate curses into some kind of flexible event loop.

This leaves me with the following options:

 * Completely avoiding ncurses for input handling.
   Given that an input fd is not required for ncurses to function
   properly.
   This obviously only works in ncurses/Unix.
 * Using a threading-build of ncurses might help!?
   But these builds are not provided by common Linux distributions.
   Also it would be a ncurses-only solution.
 * Polling input keys. I'm fearing the performance implications
   of doing this a few thousand times a second, but doing it
   every 100ms might be sufficient actually.
   After all we're talking about __keyboard__ input and
   asynchronous interruptions.
   Problem with this is: Polling is not always straight forward.
   E.g. sometimes I'm blocking waiting for some external process
   to finish. But even there it would be possible.

So it seams that the best way to go would be relying on ^C and
SIGINT on ncurses+Unix and providing a fallback on all other
Curses platforms that uses nodelay() plus getch() polling every
100ms (or every n iterations) or so and my own keyboard input buffer.

> > This is esp. important for PDCurses builds (as there is currently no
> > way to interrupt
> > a long-running process) but I'm aware that PDCurses may behave
> > completely different
> > with regard to threading.
> 
> actually, I have not noticed any particular treatment of threading in
> PDCurses (the same limitations may apply).
>
Me neither. I couldn't find a word about threading in the PDCurses
documentation.

Best regards,
Robin



reply via email to

[Prev in Thread] Current Thread [Next in Thread]