Re: Independent thread fireing events in ATL Service synchronization requirements?

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: Alexander Nickolov (agnickolov_at_mvps.org)
Date: 09/16/04


Date: Thu, 16 Sep 2004 10:18:02 -0700

Did you lock while adding and removing your objects to the list?
If you did this porperly, your object cannot be gone while you
are firing the events, since the lock is maintained around the entire
loop. However, make sure you have a dedicated thread for
event firing, and that no object is destroyed within the event
handler, otherwise locking may not be sufficient (due to reentrancy).

-- 
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD
email: agnickolov@mvps.org
MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================
"Phil Ten" <pt@dafweb.com> wrote in message 
news:eTX34C%23mEHA.3428@TK2MSFTNGP11.phx.gbl...
> Thank you for your post. I followed your recommandations
> and made my client list a class with synchronization inside
> and a lock around the entire loop.
>
> To test if closing the COM object while firing events is handled
> correctly, I modified my external thread so it would continuously
> fire events. Then using a VBA application I create and delete
> the COM object also continuously.
>
> Most of the time it works fine, however, from time to time
> I get an exception. In the debugger I could see that the
> pointer on my COM object is valid (thanks to the
> synchronization inside the client list class) but variable
> m_vec is null (m_pSize=0, m_ppUnk=0x0000000).
>
> Unfortunately, the ATL code inside the CProxy_XXXX class in the
> Fire_XXXXX function tries to execute
>
> CComPtr<IUnknown> punkConnection = m_vec.GetAt(iConnection);
>
> which fails since m_vec is NULL.
>
> At this point, my guess is that the lock for the COM object
> pointer is not enough and that I would also need to lock
> somehow the connection with the client???
>
> Thanks again for your help.
>
> Phil. Ten.
>
>
>
> "Alexander Nickolov" <agnickolov@mvps.org> wrote in message
> news:eCY3dS0mEHA.3328@TK2MSFTNGP10.phx.gbl...
>> You'll need synchronization for your list all right. The best place
>> would be in your global class of course. E.g. instead of using
>> STL list directly, wrap it in a class that exposes methods for
>> your objects to call and those methods provide the necessary
>> synchronization. This falls under my last comment - you need
>> proper synchronization for your data. The iteration will be a
>> bottleneck, however, since you need to maintain the lock around
>> the entire loop notifying your objects.
>>
>> -- 
>> =====================================
>> Alexander Nickolov
>> Microsoft MVP [VC], MCSD
>> email: agnickolov@mvps.org
>> MVP VC FAQ: http://www.mvps.org/vcfaq
>> =====================================
>>
>> "Phil Ten" <pt@dafweb.com> wrote in message
>> news:Or5$7gwmEHA.556@tk2msftngp13.phx.gbl...
>> > Sorry, I sent the previous post by mistake before finishing it.
>> >
>> > Thanks again for your post. It helps but the answer to my first
>> > point in my initial post is still unclear for me.
>> >
>> > I will rephrase it here. I currently maintain a list of all
>> > active instances of my COM object by adding the pointer
>> > on the object to an STL list in the constructor of the object:
>> >
>> > CDirWatch::CDirWatch()
>> > {
>> >    ClientsList.insert(this);
>> > }
>> >
>> > I remove the pointer from my list in the destructor of the
>> > COM obect:
>> >
>> > CDirWatch::~CDirWatch()
>> > {
>> >    ClientsList.erase(this);
>> > }
>> >
>> > My independent thread fires event using all pointers
>> > found in the list:
>> >
>> > CDirWatchItemList::iterator i;
>> > for (i=ClientsList.begin();i!=ClientsList.end();i++)
>> > {
>> >    (*i)->Fire_Notification(MyData);
>> > }
>> >
>> > My questions are:
>> >
>> > 1) Is the COM object Constructor/Destructor a good
>> > location to add/remove pointers from my global list?
>> >
>> > 2) Obviously, for each loop the object may have been
>> > destroyed just after extracting the pointer out of my list
>> > and therefore the call to "Fire_Notification" will fail
>> > because the pointer is no longer valid. How could I
>> > lock all existing COM instances while I loop though the
>> > list and fire events?
>> >
>> > Thanks again for all help.
>> >
>> > Phil Ten
>> >
>> >
>> > "Alexander Nickolov" <agnickolov@mvps.org> wrote in message
>> > news:O0t8JIqmEHA.1652@TK2MSFTNGP09.phx.gbl...
>> >> Ok, you need synchronization in the code manipulating and
>> >> accessing the m_vec array of sink pointers. ATL already does
>> >> this for you in two places - IConnectionPointImpl<> and the
>> >> proxy class used for firing your events. If you don't deviate
>> >> from these two, you don't need any extra synchronization in
>> >> your code as far as firing the events. Any extra synchronization
>> >> with regards to your object's internal state is entirely up to you.
>> >> I hope this answers your question.
>> >>
>> >> -- 
>> >> =====================================
>> >> Alexander Nickolov
>> >> Microsoft MVP [VC], MCSD
>> >> email: agnickolov@mvps.org
>> >> MVP VC FAQ: http://www.mvps.org/vcfaq
>> >> =====================================
>> >>
>> >> "Phil Ten" <pt@dafweb.com> wrote in message
>> >> news:ut7yzHpmEHA.1652@TK2MSFTNGP09.phx.gbl...
>> >> > Thank you for your post.
>> >> >
>> >> > I specified the free threading model for my object.
>> >> >
>> >> > I use ATL 7, I defined _ATL_FREE_THREADED in the
>> >> > StdAfx.h file. I checked how the code is initializing, and
>> >> > I could see that "CoInitializeEx(NULL, COINIT_MULTITHREADED)"
>> >> > is called.
>> >> >
>> >> > I hope this is the information you requested.
>> >> >
>> >> > Thanks again for all help.
>> >> >
>> >> > Phil. Ten.
>> >> >
>> >> >
>> >> > "Alexander Nickolov" <agnickolov@mvps.org> wrote in message
>> >> > news:OUQfYSomEHA.4068@tk2msftngp13.phx.gbl...
>> >> >> The most important question to ask first is: what is the
>> >> >> threading model of your object? Depending on the answer
>> >> >> you proceed completely differently.
>> >> >>
>> >> >> -- 
>> >> >> =====================================
>> >> >> Alexander Nickolov
>> >> >> Microsoft MVP [VC], MCSD
>> >> >> email: agnickolov@mvps.org
>> >> >> MVP VC FAQ: http://www.mvps.org/vcfaq
>> >> >> =====================================
>> >> >>
>> >> >> "Phil Ten" <pt@dafweb.com> wrote in message
>> >> >> news:ePmX5vjmEHA.4064@TK2MSFTNGP14.phx.gbl...
>> >> >> > Hello,
>> >> >> >
>> >> >> > I am writing an ATL service which fires events
>> >> >> > from an independent thread.
>> >> >> >
>> >> >> > My base code to fires events seem to work correctly.
>> >> >> > However, I still to need to implement synchronization
>> >> >> > features to fire events only when possible. I am
>> >> >> > familar with threads synchronization functions but,
>> >> >> > for this project (COM objects in an ATL
>> >> >> > service) I have no idea where I should implement
>> >> >> > my synchronization routines.
>> >> >> >
>> >> >> > In particular, I can see these two points:
>> >> >> >
>> >> >> > 1) Do my need to maintain my own global list of pointers
>> >> >> > pointing active COM clients, or is there a way
>> >> >> > to retreive such a list?
>> >> >> >
>> >> >> > If I must maintain my own list of pointers, where
>> >> >> > should I implement my code in the COM object class
>> >> >> > to add/remove items to my global list?
>> >> >> >
>> >> >> > 2) I assume that when the independent thread fires an event,
>> >> >> > I must use synchronization routines to be sure that
>> >> >> > the COM client will remain usable until the return of
>> >> >> > the fire_event function. If this is correct, where in the
>> >> >> > COM object classshould I implement my synchronization routines
>> >> >> > for this purpose?
>> >> >> >
>> >> >> > 3) Is there other pitfalls I should be aware of?
>> >> >> >
>> >> >> > Thank you in advance for all help.
>> >> >> >
>> >> >> > Phil. Ten.
>> >> >> >
>> >> >> >
>> >> >> >
>> >> >>
>> >> >>
>> >> >
>> >> >
>> >>
>> >>
>> >
>> >
>>
>>
>
> 


Relevant Pages

  • Re: Independent thread fireing events in ATL Service synchronization requirements?
    ... and made my client list a class with synchronization inside ... my guess is that the lock for the COM object ... pointer is not enough and that I would also need to lock ... > the entire loop notifying your objects. ...
    (microsoft.public.vc.atl)
  • Re: Independent thread fireing events in ATL Service synchronization requirements?
    ... and hence the loop will not execute, ... m_vec itself is not a pointer, so it cannot be NULL for sure. ... >> Did you lock while adding and removing your objects to the list? ... >>> and made my client list a class with synchronization inside ...
    (microsoft.public.vc.atl)
  • Re: [PATCH] mm: fix hang on anon_vma->root->lock
    ... page_lock_anon_vma() hold and must hold page lock. ... A change in the pointer to the root is covered by the ACCESS_ONCE: ... SLAB_DESTROY_BY_RCU does not guarantee that the object stays the same nor ... The only guarantee of that would be through other synchronization ...
    (Linux-Kernel)
  • Re: [PATCH] mm: fix hang on anon_vma->root->lock
    ... As far as I can tell you would have to recheck the mapping pointer and the ... pointer to the root too after taking the lock because only taking the lock ... SLAB_DESTROY_BY_RCU does not guarantee that the object stays the same nor ... The only guarantee of that would be through other synchronization ...
    (Linux-Kernel)
  • Re: Multi Threading Options
    ... If the avatars struct could be modified by any other thread, ... your modifications are so short that releasing the main lock and locking just ... Given that the refresh is timer=based, you could probably eliminate all synchronization ... If it is a UI thread, then while the drawing is happening, the PostMessage ...
    (microsoft.public.vc.mfc)