Problem: The application sometimes hangs during normal
operation. The hang is more prominent in case of more overlap window usage.
.
Analysis: The problem occurred
rarely and in some operating systems. There were no clear steps on how and why
the hang happens. On debugging the hang dumps from customers site, it pointed to
fact that the hang happens while releasing a com object of the process. The
application used smart class auto pointers like CComPtr and CComQIPtr for creating
and deleting the com objects. On more digging the dump files we could notice
that the com object thread where it was created is not available in the dump
files. Com objects are created on the thread where we call co-create instance.
In case of overlaps opened from the application, each overlap is a different
thread. And it is possible to open another overlap from the already opened overlap
via context menu. Hence the parent of the new overlap is the first overlap that
was opened from the main thread of the application. And this was the trigger
for the issue. Sometimes the user may close the parent overlap before closing the
child overlap. In that case if the child overlap or parent overlap is being referred by some
other thread, for example main thread then it would throw an exception if the
com framework tries to destroy an null com object. And this was the case in our
hang also, the overlap information is maintained by the main thread for some other
functionality. When main thread tries to release the com objects owned by overlap threads, then the
application would hang if it tries to release NULL com objects (when the overlap thread dies, it releases all the objects it owns).
Solution: The solution of this
issue was to follow the factory design pattern. All the overlap thread creation was
passed on to the main thread of the application. Hence the creation and
destruction of the threads are fully maintained under the control of the
application. Instead of passing the com objects directly between the threads, unique
Id of the com objects were passed. The user of this com objects then can use
the ID’s of the com object and request the main thread for the com object. Reference
handling being managed by the main thread of the process, the life time handling of the com objects thus been taken care. This fixed the issue
without breaking any of the existing functionality of the application.
Comments
Post a Comment