Circular (COM) reference when using IDispEventSimpleImpl - com

My question is about sinking COM events from a sub object properly, without creating a circular reference that would lead to memory leak(s).
There is an ActiveX control called CMyControl. This control creates an instance of an embedded web browser (IWebBrowser2) internally to display some HTML-content.
The web browser exposes an event source called DWebBrowserEvents2 that can deliver some interesting progress updates to CMyControl. Such as DocumentComplete when the HTML document has been fully loaded or when an error occurs etc.
And CMyControl will handle these events with the help of IDispEventSimpleImpl.
The issue I'm facing is that instances of CMyControl do not get destroyed when Release is called.
The direct reason for this is that the reference counter always ends up at 1 instead of 0.
Turns out that IDispEventSimpleImpl is indirectly responsible for this. This makes sense to me because the web browser needs the control's interface to sink the events, so it keeps a reference. Until you call the IDispEventSimpleImpl::DispEventUnadvise method, then the interface gets released.
But when Release gets called on IMyControl, the event source won't get disconnected.
I understand that: there is no reason why it would do that: Release doesn't even know about it.
Stumbled upon this post where they advise (pun intended) to create a custom "sink" object:
https://microsoft.public.vc.atl.narkive.com/4MgGRavd/dispeventadvise-dispeventunadvise-problem
The idea is that the sink object would see the events fired by the web browser first, before passing them on to CMyControl.
For this, an instance of this sink object would be stored inside CMyControl.
The sink object the connects to (and gets referenced by) the browser instead of the CMyControl instance itself. This breaks the circular reference.
Furthermore, the sink object gets passed a pointer to the "mothership" (the CMyControl instance) so it can perform a callback whenever an events occurs.
My question is: is this really how it should be done? isn't there a better/proper way to connect the events?

Related

What error should I return when a COM object has been deleted but is being attempted to be referenced?

I have extended an API in C++ written on a legacy framework that is used via JavaScript/VB. There is an object that can create from another object. However, the coder can hold on to that object (it's exposed) and do operations on it. Also, the object can be deleted. Because of that last part, I need to keep the object around, even when it is deleted in case the developer tries to reference through that object, and if they attempt to do so, return an error (HRESULT), otherwise, it could cause a crash.
What is the best common HRESULT that I should use? I can't seem to find one that matches what I want.
The only one that I found the winerr.h file that might be relivant is ERROR_FLT_DELETING_OBJECT, but I don't think it is meant for that.
EDIT
Perhaps I should not use the word delete and replace it with instead detach. The object is to be detached from the main object, but is still lives on till the gc cleans up. However, if the user were to attempt to use this detached object, I want them to wake up to the fact that they have already detached it and that they shouldn't be playing with it any more.
EXAMPLE
var newObj = container.create_newObject();
newObj.doStuff();
container.doStuffWithNewObject(newObject);
container.RemoveObject(newObj);
newObj.doStuff(); // ERROR - see, still have reference and attempting to do stuff.
container.doStuffWithNewObject(newObject); // ERROR

Apache ignite listening to state change of objects in local nodes

I am investigating a use case where ignite has to listen to changes of a property of an object in the data grid and do some operations on that object. For performance, I want the processing to be done on the same node where the data is.
How can I get an event when the property of a object has changed to a specific value (eg. Object 'X' has a property 'state' which is set to 'scheduled' from 'created') and make sure that only events are taken from the node where the object lives in?
How can I make sure that when I got the event and start processing it, nobody else changes the object (only read is allowed) until processing is finished (in other words, a transaction starts as soon as the event is picked up)?
How can I make sure that the processing code is deployed to all nodes (processing is stateless) and that it only operates on local data (without having a hard link between data object and code, in other words, if the processing code is updated in the future, the objects stay untouched)
What I got from the docs is the following:
// Local listener that listenes to local events.
IgnitePredicate<CacheEvent> locLsnr = evt -> {
// CODE
return result;
};
// Subscribe to specified cache events occuring on local node.
ignite.events().localListen(locLsnr,
EventType.EVT_CACHE_OBJECT_PUT);
In the CODE block; I have to check for a state change on 'evt.newValue()', can't that be done earlier? Ie. as a paremeter to localListen somehow?
In the CODE block, is the Object locked until I return the result? In other words, is it in here that I am sure nobody can changes the object and that I can safely change my Object? IMO it is a strange place to do that in a 'Predicate' definition and not in a handler class.
Sven
Sven,
Your code looks correct and should work as you expect. Answering your questions:
Event listener is called right after the value is updated, so I think it's OK to check the field you're interested in inside the listener. If the field is not changed, just return right away.
The object is locked, because listener is called inside the sync block for the entry. You can modify the same object, but I would not recommend to execute any sync operations like cache updates inside the listener because it's error-prone and can affect performance. You should do this asynchronously, so that the lock is released as soon as possible.

Changing Mule Flow Threading Profile at runtime

I have a requirement in hand where I need to change the Mule Flow Threading Behavior at runtime without the need of bouncing the whole Mule Container. I figured out few different ways to achieve this, but none of them are working.
I tried accessing the Mule Context Registry and from there I was trying to do a lookup of "FlowConstructLifecycleManager" Object so that I can tap in there and access the threading profile of the object and reset those values, then stop and start the flow programmatically in order to get the change applied in the flow. I am stuck in this approach as I was unable to get hold of the FlowConstructLifecycleManager Object neither from the Mule Spring Registry nor from the Transient Registry. I was able to get hold of the Flow object though which has a direct reference to that FlowConstructLifecycleManager Object. But, unfortunately, they made this object as protected and didn't expose any method for us to access this object.
Since I was unable to access this FlowConstructLifecycleManager directly from Mule implemented Flow class, I decided to extend this Flow class and just add another public method to it so that I can access FlowConstructLifecycleManager object from Flow object programmatically. But, I am stuck in this approach as well as even if I am putting my version of the same Flow class packaged and dropped in lib/user folder of the container, it is still not picking up my version of the class, and loading the original version instead.
It would be of great help if I can get any pointer on the approach of solving either my first or second problem.
Thanks in advance,
Ananya
In our company, we are building a dashboard from where we should be able to start/stop any flow or change the processing power of any flow by increasing/ decreasing the active threads for a flow or changing the pollen polling frequency. All of these should be done at runtime without any server downtime.
Anyway, I made it working finally. I had to patch up the mule-core jar and expose few objects so that I can get to the thread profile object and tweak the values at runtime and stop/ start the flow to reflect the changes to take effect. I know this is little bit messy and but it works.
Thanks,
Ananya

Media Foundation: another way to call IMFActivate::ShutdownObject?

Here is a question about IMFActivate::ActivateObject and IMFActivate::ShutdownObject in Media Foundation.
According to MSDN, the component that calls ActivateObject is responsible for calling ShutdownObject.
But there are two examples not following this rule:
http://msdn.microsoft.com/en-us/library/dd388503%28VS.85%29.aspx
and
http://msdn.microsoft.com/en-us/library/dd317912%28VS.85%29.aspx
In these two examples, they call ActivateObject and then release IMFActivate interface without calling ShutdownObject method.
This is going to lead to memory leaking, right? Or there is another way to release the resource occupied by the object?
(Can I use IMFMediaSource::Shutdown to release the object instead of using IMFActivate::ShutdownObject)
Thanks in advance.
You're right that you're supposed to call IMFActivate::ShutdownObject when you're done using the object you activated. However, notice that the sample in question is instantiating an IMFMediaSource to be returned in an out param.
HRESULT CreateVideoDeviceSource(IMFMediaSource **ppSource)
If CreateVideoDeviceSource were to do a ShutdownObject on the IMFMediaSource it instantiated and then hand it back to you, it would be in a shut-down state and therefore probably unusable.
To answer your question about what you're supposed to do about this, you can probably get away with a pMyMediaSource->Shutdown() after you're all done using it.
More info: IMFActivate's other use in Media Foundation is for allowing an MF object to be instantiated in a different process (useful because the MF Media Session will play DRM-protected content in a separate process); in that case, the MF Media Session will indeed call IMFActivate::ShutdownObject on any IMFActivates you gave it.

Notifications in wxWidgets?

I'm working on a small application using C++/wxWidgets, where several parts of the GUI need to be updated based on e.g. received UDP datagrams. More specifically, a secondary thread tries to keep a list of available "clients" in the network (which may come and go away) and e.g. corresponding comboboxes in the UI need to be updated to reflect the changes.
The documentation mentions that for this kind of thing EVT_UPDATE_UI would be a good choice. As far as I can understand from the sparse documentation, this event is sent automatically by the system and provides some support for assisted UI change.
However, I'd feel more comfortable using a more direct approach, i.e. where e.g. a window object could register/subscribe to receive notifications (either events or callbacks) upon particular events and another part of the code is sending out these notifications when required. I could do this in C++ using my own code, however I guess if wxWidgets already supports something like that, I should make use of it. However I haven't found anything in that regards.
So, the question is: does wxWidgets support this kind of notification system (or similar alternatives) or would I be best served coding my own?
AFAIK there is nothing directly usable in wxWidgets, but doing it on your own seems easy.
What I would do:
Create a wxEvtHandler-descendent class to hold the list of available "clients" in the network. Let this class have a wxCriticalSection, and use a wxCriticalSectionLocker for that in all methods that add or delete "clients".
Create a worker thread class by inheriting wxThread to handle your UDP datagrams, using blocking calls. The thread should directly call methods of the client list object whenever a client has to be added or removed. In these methods update the list of clients, and ::wxPostEvent() an event to itself (this will execute the whole notification calls in the main GUI thread).
Handle the event in the client list class, and notify all listeners that the list of clients has changed. The observer pattern seems to me a good fit. You could either call a method of all registered listeners directly, or send a wxCommandEvent to them.
Have you tried calling Update() on the widget(s) that change? Once you update the contents of the combo box, call Update(), and the contents should update.