From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Can I do a CmtGetLock while processing a EVENT_SELECTION_CHANGE

I've been attempting to use the new tree control and running into a multitasking blocking issue.

To demonstrate the issue, I've inserted about six lines of code into the Treeevent sample. See the attached Tree-Event_CmtGetLock_Issue.zip file. Inserted lines are marked with "// [ADDED]".

The situation is that on an EVENT_SELECTION_CHANGE event I want to call another routine of mine that is protected from multiple reentry by a lockout semaphore.

The result is an application lockup. No further events are processed. If running under the debugger the application may only be terminated, but not broken. But if I step the debugger through the CmtGetLock things proceed as expected. (I can only gu
ess that since a single click many times generates two EVENT_SELECTION_CHANGE events at the same time,
that they're getting somehow twisted up in the CmtGetLock. Dunno.)

Are there restrictions on calling lockout semaphores when processing some events?

Is there a better way to do all this?
0 Kudos
Message 1 of 3
(2,738 Views)
Let me explain what you are seeing. First off, a little about the EVENT_SELECTION_CHANGE event on the tree control. If you read the help for this event, you will see that it is fired every time an item is selected OR unselected. The reason for this is that the tree control supports selecting multiple items. If you are holding down CTRL, for example, it will select a new item, without unselecting the previous item (just like in Windows Explorer). Because of this, for normal selecting of items (without CTRL or SHIFT), you will get TWO EVENT_SELECTION_CHANGE events. One for the previous item being unselected, and one for the item you clicked on being selected.

So, that means your program is getting 2 events that are calling this callback. This is the
first part of the problem. The second part is the way you set up the thread lock. When you created the thread lock, you specified that you wanted it to process events while waiting for the lock by passing the constant OPT_TL_PROCESS_EVENTS_WHILE_WAITING to the function. This means that when you call CmtGetLock it will internally be processing events while waiting for the lock. It's kind of like putting a ProcessSystemEvents() in your code at that spot. So, what is happening is, your code is getting to the CmtGetLock function which is internally processing the next event (which is another EVENT_SELECTION_CHANGE), so your callback function gets called again re-entrantly. This means that CmtGetLock gets called again, and now the lock is already held, so it blocks the thread there.

Fun stuff, huh? Anyway, you can easily resolve this by creating you lock to not process messages while waiting with:

CmtNewLock (NULL, 0, &hTestLock);

Or, if you really need it to process mess
ages, you would have to protect your callback from the re-entrant situation using a status flag or something similar.

Best Regards,

Chris Matthews
National Instruments
Message 2 of 3
(2,738 Views)
Well, yes I knew about both events firing off, and your description is exactly what I suspected. But in my real case, the creation of the lock is embedded in the other routine, so I was reluctant to go "fixing" the library if it wasn't the real culprit. From (mis-)reading the CmtNewLock documentation, it wasn't clear to me until now that OTHER tasks would still be processing events if I took out the OPT_TL_PROCESS_EVENTS_WHILE_WAITING. But now I'm convinced.

Thanks Chris. I appreciate the wonderful support here.
0 Kudos
Message 3 of 3
(2,738 Views)