rthornton128 / goncurses

NCurses Library for Go
Other
383 stars 51 forks source link

Garbled output sometimes when printing #7

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
Run the attached program: go run bug.go

What is the expected output? What do you see instead?
On the first call to redraw_screen(), sometimes the output is very garbled.

What version of the product are you using? On what operating system?
go version go1.0.3
goncurses: today I did an update, so the latest version, as of today 2.2.13, I 
think (go get -u ...)
OS: Arch Linux
core/ncurses 5.9-3
multilib/lib32-ncurses 5.9-1 (I use a 64 bit system)

Please provide any additional information below.

If you press the "r" key, then the message appears as intended. (It only 
appears garbled the first time.)

If I remove the code for the goroutine for checking of new keyboard input, then 
everything works fine. (go poll_keyboard())

I've just noticed the ncurses version doesn't match the version of the 32-bit 
compatibility library... Might this have something to do with it?

Original issue reported on code.google.com by tobyjw...@gmail.com on 2 Feb 2013 at 12:15

Attachments:

GoogleCodeExporter commented 9 years ago
I ran the attached code submission but was unable to reproduce the reported 
output. Also, the output on line 49, for example, should never be visible 
because the border will always overwrite the output.

Can you provide an example of the output? 

It is also possible the version mismatch is causing your issue. Have you tried 
writing and compiling the same example in C? Does it provide the desired output 
or does it suffer from the same problem?

Original comment by rthornto...@gmail.com on 2 Feb 2013 at 11:59

GoogleCodeExporter commented 9 years ago
Ah, sorry, forgot to paste some sample output. This is what I get if I comment 
out the border line:
---------------------------------
WHAT WHTATH THEE  FUCFUKC!K?!?

q q QuQiuitt -  r -R efrre shRefresh
---------------------------------
It isn't always mixed up in the same way, here is another example:
---------------------------------
WHAT THE FUCKW!?HAT THE FUCK!?

qq  QuQitui - tr -  rR Referefrseshh
---------------------------------
Sometimes, about once out of every four runs, the output looks normal.

... Will try running the code on my 32-bit machine, and I'll also try it in C...

Original comment by tobyjw...@gmail.com on 3 Feb 2013 at 6:50

GoogleCodeExporter commented 9 years ago

Original comment by rthornto...@gmail.com on 7 Jun 2013 at 1:47

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
So this is probably because the ncurses library is NOT thread safe, and go is 
... nothing but that ;). For me personally I've worked around this via a global 
curses sync.Mutex and then using the pattern:

go func(){CURSES.Lock()
    Any goncurses code here
CURSES.Unlock()}()

I don't have my input/getch code in that though. I haven't tried putting my 
input code in there, but i could see it blocking /all/ updates until you type 
something. Also I don't know what the go func(){ ... }() is necessary, but it 
helps resolve any deadlocks you might get into by throwing it all in concurrent 
activities and the updates will sort themselves out as they finish. 

Perhaps it would be useful for the library to have a lock that was applied to 
all of these functions (optionally able to turn on/off?)

Attached is an example that produces the error, and a flag to use locks (which 
resolves the error).

Original comment by TheEpicS...@gmail.com on 14 Jun 2013 at 3:45

GoogleCodeExporter commented 9 years ago
... I don't see my file attached. Attempting to attach again.

Original comment by TheEpicS...@gmail.com on 14 Jun 2013 at 3:46

Attachments:

GoogleCodeExporter commented 9 years ago
Thank you for your insight. This might be a good solution. It would require any 
functions producing output to check the global lock which could produce a 
bottleneck unless, as you say, there were a method to turn it on or off. 
Something akin to transactions where you can start/end sections which do writes 
to screen. I'll ponder this a bit and see if I can't come up with an elegant 
solution.

Original comment by rthornto...@gmail.com on 14 Jun 2013 at 4:34

GoogleCodeExporter commented 9 years ago
After further research into the issue, it looks like the solution isn't as 
simple as using a simple mutex. ncurses may provide the functions use_window 
and use_screen which act as a global mutex inside the ncurses library but I 
need to do more of an investigation on them. It appears to be an issue with how 
ncurses handles input and output rather than just multiple threads writing 
concurrently to the same window. The best solution does appear to be where 
applications should use a select to ensure input and output are mutually 
exclusive. I'll continue to investigate and test.

Original comment by rthornto...@gmail.com on 16 Jun 2013 at 6:13

GoogleCodeExporter commented 9 years ago

Original comment by rthornto...@gmail.com on 5 Dec 2013 at 4:50