09-30-2019 11:33 AM
OK, I ran across an odd race condition in some legacy code, and it took me a minute to figure out what was going on.
See attached code to reproduce. In short, a dynamically registered event with the "Lock front panel until event completes" mode selected will cause a deadlock IF that event fires, but the event is unregistered before the event is handled.
Longer version:
If you dynamically register a Value Change event and select Lock Front Panel until complete, and you have other time-intensive tasks running in other cases, then the locking event fires *during* another one of those cases, the front panel will lock up (as expected). The unexpected part for me at least is that the front panel STAYS locked after firing Unregister For Events, resulting in a deadlock as there is no way to unlock the front panel. I would expect that the "Lock Front Panel" would persist only as long as the event is registered. I'm not sure if this is expected behavior or not- but I'd assume it's not.
I know this is an odd way to program, but this example is just to reproduce the phenomenon. Is this expected behavior to anyone else?
09-30-2019 01:47 PM
Could you share your example as 2017 please?
This sounds like a case of ...
Old Joke Time!
Man goes to his doctor and complains;
Man: Every time I drink tea, I get a pain in my eye.
Doctor: Interesting! please explain in detail what your routine is.
Man: I pour tea in my cup, add some sugar, stir it a bit and then I take a sip. That is when I get the pain.
Doctor: Next time try to remember to take the spoon out of the cup.
I told and summarized that joke for my son which eventually became a inside joke between us as;
"Don't Do That"!
I would like to see exactly what you are doing because I can understand this as being expected.
Curious,
Ben
09-30-2019 01:57 PM - edited 09-30-2019 02:04 PM
Here ya go. The example is pretty silly to be sure 🙂 This is from some legacy code that needed to detect button presses some of the time, but not all of the time, so the events were registered dynamically. When I added a timeout case to it (to do some background updates if there were no buttons pressed) I started getting lockups, and I found out it was because the buttons were being detected during the timeout case. It's already fixed in my code (quick and dirty fix was to unregister inside the loop instead of outside) but overall you're right, this is not a good way to program in a "general" sense. Just something I found that confused me and I wanted to put it up for discussion 🙂
Edit: A little more explanation. It's a part of a queued state machine (ew), where the buttons needed to be monitored in the Idle case but not in any other cases. Dynamic registration was used to only listen to the buttons during the Idle case, so other presses wouldn't register during the non-Idle states, hence registering and unregistering over and over again. This actually works fine (if janky) if literally none of the cases take any real time to execute and if there's no potential to click a button during the Timeout case. There are MUCH better ways to handle UI's to be sure, but like I said- it's legacy code so it'll get a rewrite sometime around the heat death of the universe.
09-30-2019 02:17 PM
@BertMcMahan wrote:
... a part of a queued state machine (ew), ...
Double "ew".
Have you seen this Nugget by Ton about dynamic event registration?
In that Nugget you will see that an event can be re-assigned inside the event structure. If the event is re-assigned to a null object (like a constant of a control ref) that never can change, the event is effectively "shut-off".
If I have to "turn on" and "turn Off" events, I use the method he taught us and it has worked fine for me.
Not much more I can say.
Ben
09-30-2019 02:23 PM
Yes, I've used that in the past with great success. I don't think that would solve this particular issue, as the event that triggered the change would still be in the queue. IMHO, I'd expect that flushing an event that locked the front panel or unregistering for it would unlock the front panel, otherwise you do get into a situation where you can get deadlocked.