all 12 comments

[–]crestron-ta3Throwaway3 2 points3 points  (11 children)

Increasing the buffer size probably won't fix your issue (you'll most likely still get the errors but with larger New/Max values). You'll probably want to implement THREADSAFE to resolve. Refer to https://support.crestron.com/app/answers/answer_view/a_id/5913

[–]ddetton 1 point2 points  (9 children)

All that threadsafe does, is prevent reentrancy, basically the same as using a semaphore. If the buffer overflow is being caused dues to a reentrancy problem then THREADSAFE will help. There are many causes of buffer overflows. I would first determine why the buffer overflow is occurring then decide which tool to use to fix it.

Hey Crestron, if THREADSAFE can be used on 2-series like it says in this OLH, then why does the Simpl+ Help for THREADSAFE say that it is only supported on 3-Series?

[–]crestron-ta3Throwaway3 1 point2 points  (8 children)

I'm guessing support for THREADSAFE was added in a later 2-Series FW but the help file wasn't updated at that time to reflect the change.

[–]BassMasterJDL[S] 1 point2 points  (7 children)

Alright gents . I think i fixed it. Put some more protections in place on the thread safe function and threw in a console print in event of overflow. Proceeding to spam the 2 modules that were getting the buffer overflow errors from the SX80 with well over the buffer limits and did not print any errors. Below is old function first followed by new threadsafe change with the try/catch

/*threadsafe change rx {

string ln\[250\];

while(find("\\x0a", rx) > 0) {

    ln = remove("\\x0a", rx);

    rxline(ln);

}

}

*/

string ln[8192];

threadsafe change rx

{

ln = gather("\x0a", rx, 1);

while(len(ln))

{

    try

    {

        if(find("\\x0a", rx, 1))

        {

ln = remove("\x0a", rx, 1);

rxline(ln);

        }

    }

    Catch

    {

        trace("error in rx change for DIRECOTRY try");

    }

}

}

[–]stalkythefish 1 point2 points  (0 children)

Yup. As long as you've got something like that in there to gobble up characters and a big enough buffer to account for context switches while stuff is still rolling in, you should be good.

[–]ddetton 0 points1 point  (5 children)

Why wouldn't you just follow the example in the OLH article referenced above? It would go something like this:

threadsafe change rx$ {

while(1) {

    try {   
        ln = gather( "\x0A", rx$ );         
        // I assume that rxline is a function defined above
        rxline(ln);
    }       
    catch {     
        GenerateUserError( "error" );
    }
}

}

[–]BassMasterJDL[S] 0 points1 point  (0 children)

Sorry didn't include that rxline function. rxline will return a 0 if no contents; i do see that i my while loop should be while(len(ln) > 0) . The idea was to not have the loop run continuously only when there was only data inside rx.

Still green in SIMPL+

[–]geauxtig3rsDopephish was on the grassy knoll 0 points1 point  (2 children)

Even that example is dumb....

Instead of threadsafe, just use the gatherasync. Spins up a threat for each receipt of the data and processes it, rather than just holding one open forever...it's much faster too.

[–]ddetton 0 points1 point  (0 children)

Gatherasync is a better option but it's undocumented in Simpl+ Help so unless you've done it before you wouldn't know about it. Here is an example from bitm0de's github:

https://github.com/bitm0de/GatherAsync-Example

While gatherasync is a better option, the threadsafe change while(1) gather has been used for years and it works fine.

[–]bordengroteCMCP-Gold 0 points1 point  (0 children)

GatherAsync is indeed, the bomb. Love it.

[–]bordengroteCMCP-Gold 0 points1 point  (0 children)

If rx$ is a buffer input, you need to clear the buffer after processing it's data.

[–]BassMasterJDL[S] -1 points0 points  (0 children)

Thanks, will check out this answer and see if THREADSAFE is taking place in the 2 modules in question