I'm using i3 (//http) with dzen (//https) bar and I'm using newlisp to build me a pretty customized bar.
I have this code to check for cpuload:
(define (read-proc-stat)
(setq procStat (open "/proc/stat" "read"))
(do-while (regex {cpud?} (read-line procStat))
(parse-stat-line (current-line)))
(close procStat))
Script runs ok for a while, with a (sleep 1000) between calls, and then spits this:
ERR: value expected in function read-line : procStat
called from user defined function read-proc-stat
called from user defined function draw-cpu-load
I added a (println procStat) and found script stopped when procStat would take value 1024, so it sounded like I was hitting an OS limit there. So I wrote a new script to test that:
(define (read-proc-stat)
(setq proc-stat (open "/proc/stat" "read"))
(println "open handle: " proc-stat)
(do-while (regex {cpud?} (read-line proc-stat))
(println (current-line)))
(close proc-stat))
(while true
(read-proc-stat)
(sleep 1000))
With this script the opening handle remains constant (at value 4 in my test).
The difference with the "real" script is that I have a status script that loads a cpuload module which contains read-proc-stat function definition.
I wonder why same function gets a constant handle when I call it one way and an incremented one (in steps of 4) when I call it the other way.
I modified read-proc-stat like this:
(define (read-proc-stat:read-proc-stat)
(if (nil? read-proc-stat:procStat)
(setq read-proc-stat:procStat (open "/proc/stat" "read")))
(do-while (regex {cpud?} (read-line read-proc-stat:procStat))
(parse-stat-line (current-line)))
(seek read-proc-stat:procStat 0))
Which fixed the issue. But now I wonder: since I'm not closing the file ever, does newlisp close opened file handles when script finishes? What if it finishes with ctrl-c or what if it explodes on some other part? Does it do a proper cleaning?
On this simpler program:
(define (read-stat)
(setq handle (open "foo.txt" "read")) ; foo contains 10 lines with: abcdefg
(while (read-line handle) (println (current-line)))
(println handle) (close handle))
I cannot repeat the behavior, you are seeing (incrementing of file handles). Also when exiting newLISP with Ctl-C or exists otherwise, a new newLISP session will not increment the file handle, but always create the same file handle.
ps: also - unrelated - why are you using 'do-while' instead of 'while'. Shouldn't the regex test take place always after reading a line from the file?
Quote from: "Lutz"
On this simpler program:
...
I cannot repeat the behavior, you are seeing (incrementing of file handles).
Yes, called directly it behaves fine. So I rolled back my git repo and uploaded the bogus version with some additions to denote the bug.
I put it here: //https://gitorious.org/bogus-stuff/dzenbar-bogus
(I realized just now, when replying this message, that I could have attached the code to the message)
Run status and you'll get increasing file handles. Run try.it.alone.lsp and you'll see the (almost) same code (parse-stat-line replaced with a println) behaving ok, like in your simpler script.
Also I included an error.log which is a full run of status until it blows up.
Quote from: "Lutz"
ps: also - unrelated - why are you using 'do-while' instead of 'while'. Shouldn't the regex test take place always after reading a line from the file?
Because I'm a moron! :P
In fact I had a while before, but had what I thought was a convoluted exit condition, you can check it out with
git log -p 48317b302b67e820e8d0a9816267d5a42c68f16e
The thing is that in theory is wrong, but in practice it seems I'm setting something somewhere that avoids parse-stat-line from exploding. And since it doesn't blow up, it's unseen since this runs once per second.