Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Search instead for 
Did you mean: 
greubel
Level 7

Screensaver and msg port

How does Roku handle screensaver and msg ports ?
I've noticed that if I have active sockets, I get a lot of false msg responses.
This is indicative of the problem of select() when you don't drain the queued messages.
All of my objects are linked to three global msg ports. When the screensaver activates, I start getting errors.
The "* LOG SKT" entries are generated by an input socket event with NO data.
roSocketEvent UDP Broadcast 995757880 readable True MAX 14 CUR 1
Received Broadcast message: 192.168.1.4:64276 KNOWN http://192.168.1.4:8895/deviceDescription/204683ed-9f48-3c47-b70d-0da4ab7276fa for Windows 7, UPnP/1.0 DLNADOC/1.50, Serviio/1.4.1.2
Msg Queue 0 / 0 / 0
* LOG SKT UDP Broadcast errors = 212 MAX 14 CUR 1
drained 0 items
Msg Queue 0 / 0 / 0
roSocketEvent UDP Broadcast 995757880 readable True MAX 14 CUR 1
Received Broadcast message: 192.168.1.4:1030 M-SEARCH ST: urn:schemas-upnp-org:device:RemoteUIClientDevice:1
Msg Queue 0 / 0 / 0
roSocketEvent UDP Broadcast 995757880 readable True MAX 14 CUR 1
Received Broadcast message: 192.168.1.4:1030 M-SEARCH ST: urn:schemas-upnp-org:device:InternetGatewayDevice:1
Msg Queue 0 / 0 / 0
* LOG SKT UDP Broadcast errors = 213 MAX 14 CUR 1
drained 0 items

After about two minutes, I stop getting any traces at all from the Telnet debug console ???
Then when I click a button, the Telnet console resumes and the screensaver exits and I get a VERY large number of msg events queued.
The "Msg Queue" entries show the counts of each of my ports. The last is the one I use for sockets.
102351 msg events is a lot !
* Garbage roAssociativeArray
. COUNT: 84736
. ORPHANED: 0
. ROOT: 83
* Set Timer - GA_Idle now 1433936 expires 1443936
* Timed queue return - 822659
Msg Queue 0 / 0 / 102351
roSocketEvent UDP Broadcast 995757880 readable True MAX 81771 CUR 81771
Received Broadcast message: 192.168.1.4:1030 M-SEARCH ST: urnSmiley Tonguev-com:device:WebdavServer:1
Now 1438725 expires 678124
* Timed queue activate - UDP_Search
Udp Search (101) rootdevice OK, MediaServer OK, Notify OK
* Set Timer - UDP_Search now 1438744 expires 1558744
* Timed queue return - 23
Msg Queue 0 / 0 / 3


This causes the remote to be very sluggish or fails to respond and may even crash if the screensaver is active for a long period.
The large counts only show up on 3.x boxes, where the no data msgs apply to all.

What is the mechanism that screen saving employs. Is the intermediate code actually testing my ports and passing it on to the screensaver ?
I thought that the screensaver preempted my activity but I'm still able to get some interrupts even though it is active ???

I put in a kludge that if the queue count was over 25, just through them away ? Not a very good practice but it clears the problem.
0 Kudos
7 Replies
Roku Employee
Roku Employee

Re: Screensaver and msg port

I'm not completely sure I understand the problem, I'll reread your post a few times, but screensaver does not preempt the current channel, it runs in its own thread, but has r/w access to the same tmp:/ pkg:/ and registry as the channel. If you have a screensaver signed with the same DevID but is a separate channel it should still share registry and tmp:/ access.

Does your screensaver use the sockets functions too, or just the channel?

- Joel
0 Kudos
greubel
Level 7

Re: Screensaver and msg port

The screensaver is the standard default Roku screensaver. Either bouncing clock or "Roku". I have it set to go off at 5 minutes.
It shouldn't know anything about my channel. That is why I'm puzzled why my socket data / msg events are going flakey ???
0 Kudos
Roku Employee
Roku Employee

Re: Screensaver and msg port

Ah, I see, that is weird. Let me check in with engineering and see if there is any useful info. You might wind up having to use a bit of a hack and implement your own faux screensaver in your channel.

- Joel
0 Kudos
greubel
Level 7

Re: Screensaver and msg port

I tried PlayOn's screensaver and it works fine.
One thing I didn't mention was that this is in conjunction with pausing a video and waiting for the screensaver to kick in.
Then wait for a couple more minutes and then clicking the remote.
0 Kudos
EnTerr
Level 8

Re: Screensaver and msg port

"greubel" wrote:
...
After about two minutes, I stop getting any traces at all from the Telnet debug console ???
Then when I click a button, the Telnet console resumes and the screensaver exits and I get a VERY large number of msg events queued.
The "Msg Queue" entries show the counts of each of my ports. The last is the one I use for sockets.
102351 msg events is a lot !
* Garbage roAssociativeArray
. COUNT: 84736
. ORPHANED: 0
. ROOT: 83
* Set Timer - GA_Idle now 1433936 expires 1443936
* Timed queue return - 822659
Msg Queue 0 / 0 / 102351
...
...
What is the mechanism that screen saving employs. Is the intermediate code actually testing my ports and passing it on to the screensaver ?
I thought that the screensaver preempted my activity but I'm still able to get some interrupts even though it is active ???

I put in a kludge that if the queue count was over 25, just through them away ? Not a very good practice but it clears the problem.

I also re-read your question multiple times but still don't understand* most of it. So i trimmed down to the parts that i think i get.
I have one question and two comments:
  • How do you know how many messages are waiting on a port, it does not have .count(), does it? Cue the "102351" and "25" queue counts above - how is that measured?

  • In my experience, when screen saver is activated - original content continues running. I have not measured it before but just did - it is running at ~1/2 the speed with screen saver (slightly slower; fw3 and 5; "LED Clock & Weather" SS).

  • I imagine that some API calls might be blocking however, e.g. if main content tried to show a screen, maybe the method call waits since UI unavailable? When you stop getting these traces in console you mention above - have you tried hitting ctrl-C and see if execution is temporarily stuck in particular part of the code?

(*) which makes me reflect and wonder if that's how others feel reading my questions.
0 Kudos
greubel
Level 7

Re: Screensaver and msg port

I use three ports for everything to try and prioritize events. You can't use msg = wait( 5, port) with sockets because of a Roku problem. I have a drain() function that removes all the events from a port and pushes them to one of my queues. When you do a wait(), Roku does an internal select() and generates msg events for all unhandled sockets. So if you have multiple sockets with data, Roku will generate an event for each of them every time you do the wait().

I think that he does this even if the port is not associated with a socket.

The 102351 is an outstanding count() of my socket queue.

Roku could fix this if they had a way to tell if the port was associated to a socket and only do the select() if there was nothing on queue.


while true ' My message loop

i = Drain_Port( m.segport, m.Pri0_Queue ) ' Look for segments
i = i + Drain_Port( m.scrport, m.Pri1_Queue ) ' Look for remote click
i = i + Drain_Port( m.port, m.Pri2_Queue ) ' Look for everything else

m.MSG_Cur = i
if i > m.MSG_Max m.MSG_Max = i

msg = invalid
if m.Pri0_Queue.Count() > 0
msg = m.Pri0_Queue.Shift()
elseif m.Pri1_Queue.Count() > 0
msg = m.Pri1_Queue.Shift()
elseif m.Pri2_Queue.Count() > 0
msg = m.Pri2_Queue.Shift()
else
msg = wait( 1, m.scrport )
end if

if msg <> invalid
Logit([ "Msg Queue ", m.Pri0_Queue.Count(), " / ", m.Pri1_Queue.Count(), " / ", m.Pri2_Queue.Count() ])
if m.Pri2_Queue.Count() > 25
m.Pri2_Queue.Clear()
end if
end if
.........................
Function Drain_Port( port as object, queue as object ) as integer
cnt = 0
msg = port.GetMessage()
while msg <> invalid
queue.Push( msg )
cnt = cnt + 1
msg = port.GetMessage()
end while
return cnt
End Function

0 Kudos
greubel
Level 7

Re: Screensaver and msg port

I wrote a simple socket routine to show the interaction of the screensaver and the application.
What it does is create a socket and post a request. It gets the incoming event but doesn't read the data to show what the screensaver does for sockets with pending data. Any socket that has data will create an event every time someone does a wait(time, port). ANY PORT !

The Roku screensaver is set to kick in at 5 minutes. After that, I get 3000 events per minute coming out of the screensaver. It could be a lot more if you have multiple active sockets. It looks like the screensaver is in a "msg = wait( 20, port )" loop.

Roku could fix the screensaver to not use wait() or fix the real problem with ports and socket association. It's my understanding that the wait function does a UNIX select() with a file mask. Well if there isn't a socket on the port, why do the select ? Also the selection file mask should only contain files for that port.

What this does to my application is, I'll get a good input event followed by several ghost events with no-data because I processed the data on the first instance,


' Test extra events comming from screen saver

Function RunUserInterface( Param as Object )
eol = Chr(13)+Chr(10)
m.device = CreateObject( "roDeviceInfo" ) ' Device table
o = m.device.GetIPAddrs()
? o
ipadrs = o.Lookup( "eth1" )

adrs = createobject( "roSocketAddress" )
adrs.setAddress( ipadrs+":8060" )

tcp = CreateObject( "roStreamSocket" )
port = CreateObject( "roMessagePort" )
tcp.SetMessagePort( port )
tcp.setSendToAddress( adrs )
tcp.NotifyReadable(true)

tcp.connect()

obuf = createobject( "roByteArray" )
obuf.FromAsciiString( "POST /keypress/Lit_X HTTP/1.1"+eol+eol )
z = obuf.Count()
obuf[z] = 0

x = tcp.send( obuf, 0, z )
? "Sent " x

msg = wait( 1000, port )
? "I have 1 " type( msg ) " on queue !"

for m=0 to 20-1
? "min " m " queue = " Drain_Port( port )
sleep( 60000 )
end for
End Function

Function Drain_Port( port as object ) as integer
cnt = 0
msg = port.GetMessage()
while msg <> invalid
cnt = cnt + 1
msg = port.GetMessage()
end while
return cnt
End Function


Results

------ Running ------
eth1: 192.168.1.11

Sent 33
I have 1 roSocketEvent on queue !
min 0 queue = 0
min 1 queue = 0
min 2 queue = 0
min 3 queue = 0
min 4 queue = 0
min 5 queue = 0
min 6 queue = 147 <----------------- Screen Saver starts
min 7 queue = 3000
min 8 queue = 2999
min 9 queue = 2999
min 10 queue = 2999
min 11 queue = 2998
min 12 queue = 2999
min 13 queue = 3000
min 14 queue = 2996
min 15 queue = 3000
min 16 queue = 2997
min 17 queue = 2999
min 18 queue = 3000
min 19 queue = 3000

0 Kudos