Welcome, Guest! Log In | Create Account

Mantis Bugtracker

Viewing Issue Simple Details Jump to Notes ] View Advanced ] Issue History ] Print ]
ID Category Severity Reproducibility Date Submitted Last Update
0000096 [Delta3D] Defect crash always 2009-10-10 19:04 2009-11-10 16:48
Reporter wooyay View Status public  
Assigned To Cowboycoder
Priority normal Resolution fixed  
Status closed   Product Version
Summary 0000096: UnregisterForMessages causes crash when called from invokable
Description Calling UnregisterForMessages modifies the GlobalMessageListenerMap in GameManager. When UnregisterForMessages is called from an invokable that is called from InvokeGlobalInvokables, the map is modified while it is being iterated. This causes a crash.

The patch changes the invokable map entry to also contain a boolean flag mKilled. Instead of erasing the invokable from the map, it is marked as killed. The next time the game manager encounters the killed entry, it cleanly erases it from the map.

Caveat 1: The GameManager may never again encounter the killed invokable, clogging the map. This could cause problems because the GameActor is referenced by RefPtr from the entry. I don't know if this can happen. The method UnregisterAllMessageListenersForActor immediately erases all invokables, maybe that's enough to clean up?

Caveat 2: Pretty much untested.
Additional Information
Tags No tags attached.
Attached Files ? file icon unregisterformessages.patch [^] (12,632 bytes) 2009-10-10 19:04

- Relationships

-  Notes
(0000224)
Cowboycoder (administrator)
2009-10-27 17:34

It seems that an iterator for a multimap (which is what the GM is using) will only be invalidated if the item the iterator is pointing to is erased. Otherwise, the iterator should remain valid.

And since InvokeGlobalInvokables() increments the iterator to the next one before calling ->Invoke(), the only time this should fail is if from Invoke(), you unregister the *next* item in the multimap.

In any case, there's still a problem lurking in there, and in other places of Delta3D where the iterator can be broken. I'm looking for a more general solution...

-Erik
(0000229)
Cowboycoder (administrator)
2009-11-04 22:56

I believe this is fixed now (I hope!) with revision 6425. I didn't use the supplied patch and instead, found a more simple solution.

Since the mGlobalMessageListeners stores ActorProxy pointers as the value, I just NULL'd it out in the Unregister() method instead of erasing it. During InvokeGlobalInvokables(), if a NULL value is found, it will erase it from the container.

This seems like a pretty simple solution - no new variables or buffered lists to sort through. The only downside I foresee is that the container could now have values of NULL in it. If existing code doesn't check for a NULL value, it will crash.

If you have a test case that proves this revision fixes the problem, I'd love to know!

Thanks,
ERik

- Issue History
Date Modified Username Field Change
2009-10-10 19:04 wooyay New Issue
2009-10-10 19:04 wooyay File Added: unregisterformessages.patch
2009-10-27 17:25 Cowboycoder Status new => assigned
2009-10-27 17:25 Cowboycoder Assigned To => Cowboycoder
2009-10-27 17:34 Cowboycoder Note Added: 0000224
2009-11-04 22:56 Cowboycoder Note Added: 0000229
2009-11-04 22:56 Cowboycoder Status assigned => resolved
2009-11-04 22:56 Cowboycoder Resolution open => fixed
2009-11-10 16:48 Cowboycoder Status resolved => closed


Mantis 1.1.8[^]
Copyright © 2000 - 2009 Mantis Group
Powered by Mantis Bugtracker