avid
August 3rd, 2004, 04:18 AM
Ben,
This might get a bit complicated, but stick with it!
I have analysed the issues which caused Rob’s lock-ups when using scrolling (marquee) text and the steps I had to take to avoid them. These have significant consequences for safe usage of the driver API.
Rob’s example showed up two problems.
1) In his use of LDJ, the Girder LUA was sending changes to NR variables which were being displayed in scrolling transparent text boxes. This then calls the text box driver’s VariableChanged method. As part of the implementation of the text boxes I have to act on the “window” which is the on-screen representation of the text button. In particular it is necessary to first hide then show transparent text, to capture the correct background. But the call to VariableChanged is on the Girder driver’s listen thread! This thread is not allowed to do Windows actions in-line. So I had to add a deferred mechanism to get the Windows actions moved from the VariableChanged method onto a “safe” thread.
2) More subtly, it is possible for the first call of PaintButton for a button to be called on Girder driver’s listen thread. This arises when a button is on a hidden frame, and then Girder LUA sends a change to the STATE variable for the frame. If this makes the frame visible, the driver sees a PaintButton call for the first time. It is not allowed to create a window in this thread and doing so will lead to threading issues. Effectively it means that it is unsafe to do any window painting inside PaintButton!! Again I had to add a deferred mechanism to get the Windows actions moved from the PaintButton method onto a “safe” thread.
In both cases, I could manage the deferred call as I was sub-classing your main window and so could post it a couple of private WM_ messages which my WndProc would handle knowing that it was safe to act. I have not yet uploaded the source with these changes, but will do so this evening.
Does the explanation make sense? Do you see the issues??
As I see it, there are four options going forward post-1.0:
1) Leave it as it is, with the AvidUtils source and this posting acting as guidance to future driver writers. It may then be necessary for any (every) driver which displays anything to sub-class the main window.
2) Leave it as it is, but make it clear in SDK documentation what the Windows re-entrancy restrictions may be.
3) Add a new “call me back on a safe thread” call which the driver can use to ensure that Windows operations are safely allowed.
4) Change NR so that calls to VariableChanged and PaintButton are only made from the Windows message thread, which is always safe.
What do you think?
Brian
This might get a bit complicated, but stick with it!
I have analysed the issues which caused Rob’s lock-ups when using scrolling (marquee) text and the steps I had to take to avoid them. These have significant consequences for safe usage of the driver API.
Rob’s example showed up two problems.
1) In his use of LDJ, the Girder LUA was sending changes to NR variables which were being displayed in scrolling transparent text boxes. This then calls the text box driver’s VariableChanged method. As part of the implementation of the text boxes I have to act on the “window” which is the on-screen representation of the text button. In particular it is necessary to first hide then show transparent text, to capture the correct background. But the call to VariableChanged is on the Girder driver’s listen thread! This thread is not allowed to do Windows actions in-line. So I had to add a deferred mechanism to get the Windows actions moved from the VariableChanged method onto a “safe” thread.
2) More subtly, it is possible for the first call of PaintButton for a button to be called on Girder driver’s listen thread. This arises when a button is on a hidden frame, and then Girder LUA sends a change to the STATE variable for the frame. If this makes the frame visible, the driver sees a PaintButton call for the first time. It is not allowed to create a window in this thread and doing so will lead to threading issues. Effectively it means that it is unsafe to do any window painting inside PaintButton!! Again I had to add a deferred mechanism to get the Windows actions moved from the PaintButton method onto a “safe” thread.
In both cases, I could manage the deferred call as I was sub-classing your main window and so could post it a couple of private WM_ messages which my WndProc would handle knowing that it was safe to act. I have not yet uploaded the source with these changes, but will do so this evening.
Does the explanation make sense? Do you see the issues??
As I see it, there are four options going forward post-1.0:
1) Leave it as it is, with the AvidUtils source and this posting acting as guidance to future driver writers. It may then be necessary for any (every) driver which displays anything to sub-class the main window.
2) Leave it as it is, but make it clear in SDK documentation what the Windows re-entrancy restrictions may be.
3) Add a new “call me back on a safe thread” call which the driver can use to ensure that Windows operations are safely allowed.
4) Change NR so that calls to VariableChanged and PaintButton are only made from the Windows message thread, which is always safe.
What do you think?
Brian