WinInet and InternetOpen - c++

The documentation states that InternetOpen can be called multiple times without any issues. My question though is should I be calling InternetCloseHandle on handle returned by it multiple times?
For example, I have a class I call CAPIRequestContext, which has a handle which is returned by InternetOpen. Each one of my requests has it's own copy. Right now, I call InternetCloseHandle in the destructor, so it gets called multiple times.
I'm wondering if the following could cause issues:
Thread A creates a CAPIRequestObject which calls InternetOpen and stores the handle. Thread B does the same, but then goes out of scope before Thread A exits, so Thread B calls the destructor in it's own CAPIRequestObject, which calls InternetCloseHandle on the handle returned by InternetOpen.
Should I remove the call to InternetCloseHandle in the destructors of my class? At least for the InternetHandle? I assume I should call InternetCloseHandle for the handle returned by HttpOpenRequest.
I have similar questions regarding the handle returned by InternetConnect. Are these handles shared?
Here is some sample code, minus some external code that I don't think is related to the issue:
class CAPIClient;
class CAPIRequest
{
public:
CAPIRequestContext()
{
m_hConn = NULL;
m_hInternet = NULL;
m_hRequest = NULL;
}
~CAPIRequestContext()
{
if (m_hRequest) InternetCloseHandle(m_hRequest);
if (m_hConn) InternetCloseHandle(m_hConn);
if (m_hInternet) InternetCloseHandle(m_hInternet);
}
bool Init(const CAPIClient &client, const std::string &uri, const std::string &method)
{
ATLASSERT(!(m_hInternet || m_hConn || m_hRequest));
if (m_hInternet || m_hConn || m_hRequest) throw std::exception("Cannot init request more than once.");
bool success = false;
m_AuthToken = *client.m_pAuthToken;
URI = uri;
m_hInternet = InternetOpen("MyApp", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
DWORD requestTimeout = 60 * 1000; // Set timeout to 60 seconds instead of 30
if (m_hInternet)
{
InternetSetOption(m_hInternet, INTERNET_OPTION_RECEIVE_TIMEOUT, &requestTimeout, sizeof(requestTimeout));
m_hConn = InternetConnect(m_hInternet, (LPSTR)client.m_host.c_str(), client.m_port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, (DWORD_PTR)this);
if (m_hConn) {
m_hRequest = HttpOpenRequest(m_hConn, method.c_str(), uri.c_str(), "HTTP/1.1", NULL, NULL, client.GetOpenRequestFlags(), 0);
}
if (m_hRequest)
{
success = true;
}
}
return success;
}
}
// There are additional calls like
// SendRequest
// GetData
// GetFullResponse
private:
// Added these methods to make sure I'm not copying the handles
enter code here
CAPIRequestContext(const CAPIRequestContext &other) = delete;
CAPIRequestContext& operator=(const CAPIRequestContext& other) = delete;
private:
HINTERNET m_hInternet;
HINTERNET m_hConn;
HINTERNET m_hRequest;
}

The documentation states that InternetOpen can be called multiple times without any issues. My question though is should I be calling InternetCloseHandle on handle returned by it multiple times?
Yes, as is stated in InternetOpen() documentation:
After the calling application has finished using the HINTERNET handle returned by InternetOpen, it must be closed using the InternetCloseHandle function.
For example, I have a class I call CAPIRequestContext, which has a handle which is returned by InternetOpen. Each one of my requests has it's own copy. Right now, I call InternetCloseHandle in the destructor, so it gets called multiple times.
That would be a correct implementation, if each instance of the class calls InternetOpen(), or otherwise obtains ownership of a unique HINTERNET.
HOWEVER, do be aware that such a class needs to implement the Rule of Three. Basically, if you have to provide a destructor to release a resource, you also need to provide a copy-constructor and copy-assignment operator as well.
But, you can't call InternetCloseHandle() multiple times on the same HINTERNET, so you can't have multiple CAPIRequestContext using the same HINTERNET and all of them calling InternetCloseHandle()1. So, your copy constructor and copy-assignment operator must either:
take ownership of the HINTERNET from the source CAPIRequestContext that is being copied.
be disabled completely to prevent copying one CAPIRequestContext to another.
In your case, I would opt for #2.
1: You would need a per-instance flag indicating which instance can call it and which ones cannot. But this is not good class design. If you need to share an HINTERNET, you should implement reference counting semantics instead, such as provided by std::shared_ptr.
I'm wondering if the following could cause issues: Thread A creates a CAPIRequestObject which calls InternetOpen and stores the handle. Thread B does the same, but then goes out of scope before Thread A exits, so Thread B calls the destructor in it's own CAPIRequestObject, which calls InternetCloseHandle on the handle returned by InternetOpen.
That is perfectly safe, provided each CAPIRequestObject has its own HINTERNET.
Should I remove the call to InternetCloseHandle in the destructors of my class?
No, if each class instance holds a unique HINTERNET.
I assume I should call InternetCloseHandle for the handle returned by HttpOpenRequest.
Yes, as is stated in the HttpOpenRequest() documentation:
After the calling application has finished using the HINTERNET handle returned by HttpOpenRequest, it must be closed using the InternetCloseHandle function.
I have similar questions regarding the handle returned by InternetConnect. Are these handles shared?
Each HINTERNET must be closed individually.

Related

Using member shared_ptr from a member callback function running in different thread (ROS topic subscription)

I am not completely sure how to best title this question since I am not completely sure what the nature of the problem actually is (I guess "how fix segfault" is not a good title).
The situation is, I have written this code:
template <typename T> class LatchedSubscriber {
private:
ros::Subscriber sub;
std::shared_ptr<T> last_received_msg;
std::shared_ptr<std::mutex> mutex;
int test;
void callback(T msg) {
std::shared_ptr<std::mutex> thread_local_mutex = mutex;
std::shared_ptr<T> thread_local_msg = last_received_msg;
if (!thread_local_mutex) {
ROS_INFO("Mutex pointer is null in callback");
}
if (!thread_local_msg) {
ROS_INFO("lrm: pointer is null in callback");
}
ROS_INFO("Test is %d", test);
std::lock_guard<std::mutex> guard(*thread_local_mutex);
*thread_local_msg = msg;
}
public:
LatchedSubscriber() {
last_received_msg = std::make_shared<T>();
mutex = std::make_shared<std::mutex>();
test = 42;
if (!mutex) {
ROS_INFO("Mutex pointer is null in constructor");
}
else {
ROS_INFO("Mutex pointer is not null in constructor");
}
}
void start(ros::NodeHandle &nh, const std::string &topic) {
sub = nh.subscribe(topic, 1000, &LatchedSubscriber<T>::callback, this);
}
T get_last_msg() {
std::lock_guard<std::mutex> guard(*mutex);
return *last_received_msg;
}
};
Essentially what it is doing is subscribing to a topic (channel), meaning that a callback function is called each time a message arrives. The job of this class is to store the last received message so the user of the class can always access it.
In the constructor I allocate a shared_ptr to the message and for a mutex to synchronize access to this message. The reason for using heap memory here is so the LatchedSubscriber can be copied and the same latched message can still be read. (the Subscriber already implements this kind of behavior where copying it doesn't do anything except for the fact that the callback stops being called once the last instance goes out of scope).
The problem is basically that the code segfaults. I am pretty sure the reason for this is that my shared pointers become null in the callback function, despite not being null in the constructor.
The ROS_INFO calls print:
Mutex pointer is not null in constructor
Mutex pointer is null in callback
lrm: pointer is null in callback
Test is 42
I don't understand how this can happen. I guess I have either misunderstood something about shared pointers, ros topic subscriptions, or both.
Things I have done:
At first I had the subscribe call happening in the constructor. I think giving the this pointer to another thread before the constructor has returned can be bad, so I moved this into a start function which is called after the object has been constructed.
There are many aspects to the thread safety of shared_ptrs it seems. At first I used mutex and last_received_msg directly in the callback. Now I have copied them into local variables hoping this would help. But it doesn't seem to make a difference.
I have added a local integer variable. I can read the integer I assigned to this variable in the constructor from the callback. Just a sanity check to make sure that the callback is actually called on an instance created by my constructor.
I think I have figured out the problem.
When subscribing I am passing the this pointer to the subscribe function along with the callback. If the LatchedSubscriber is ever copied and the original deleted, that this pointer becomes invalid, but the sub still exists so the callback keeps being called.
I didn't think this happened anywhere in my code, but the LatcedSubscriber was stored as a member inside an object which was owned by a unique pointer. It looks like make_unique might be doing some copying internally? In any case it is wrong to use the this pointer for the callback.
I ended up doing the following instead
void start(ros::NodeHandle &nh, const std::string &topic) {
auto l_mutex = mutex;
auto l_last_received_msg = last_received_msg;
boost::function<void(const T)> callback =
[l_mutex, l_last_received_msg](const T msg) {
std::lock_guard<std::mutex> guard(*l_mutex);
*l_last_received_msg = msg;
};
sub = nh.subscribe<T>(topic, 1000, callback);
}
This way copies of the two smart pointers are used with the callback instead.
Assigning the closure to a variable of type boost::function<void(const T)> seems to be necessary. Probably due to the way the subscribe function is.
This appears to have fixed the issue. I might also move the subscription into the constructor again and get rid of the start method.

Good or bad: Calling destructor in constructor [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Break: I don't think it is the same question actually, the other question is a general question about calling destructors manually. This is at the creating process, inside the class itself. Still want to know what happen when you do this, like stated in the question below.
At first, I think it is bad, real bad. Just analysing this piece of code of a constructor (see below), made by two guys and need it to translate it to Delphi object Pascal. It must behave the same like the C-version. I don't like the style, very ugly but never mind.
Another thing, at two stages in the code it calls the destructor when fail (I suppose to close the connection however the destructor is automaticly called when deleted, why want you do this anyway?). I think that is not the way to do it or do miss something inhere?
Also, after calling the destructor, they want to throw an exception (huh?) however I think this will never be executed and cause another exeption when you manually want to access it or want to delete it.
Serial::Serial(
std::string &commPortName,
int bitRate,
bool testOnStartup,
bool cycleDtrOnStartup
) {
std::wstring com_name_ws = s2ws(commPortName);
commHandle =
CreateFileW(
com_name_ws.c_str(),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL
);
if(commHandle == INVALID_HANDLE_VALUE)
throw("ERROR: Could not open com port");
else {
// set timeouts
COMMTIMEOUTS timeouts;
/* Blocking:
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
Non-blocking:
timeouts = { MAXDWORD, 0, 0, 0, 0}; */
// Non-blocking with short timeouts
timeouts.ReadIntervalTimeout = 1;
timeouts.ReadTotalTimeoutMultiplier = 1;
timeouts.ReadTotalTimeoutConstant = 1;
timeouts.WriteTotalTimeoutMultiplier = 1;
timeouts.WriteTotalTimeoutConstant = 1;
DCB dcb;
if(!SetCommTimeouts(commHandle, &timeouts)) {
Serial::~Serial(); <- Calls destructor!
throw("ERROR: Could not set com port time-outs");
}
// set DCB; disabling harware flow control; setting 1N8 mode
memset(&dcb, 0, sizeof(dcb));
dcb.DCBlength = sizeof(dcb);
dcb.BaudRate = bitRate;
dcb.fBinary = 1;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.ByteSize = 8;
if(!SetCommState(commHandle, &dcb)) {
Serial::~Serial(); <- Calls destructor!
throw("ERROR: Could not set com port parameters");
}
}
if(cycleDtrOnStartup) {
if(!EscapeCommFunction(commHandle, CLRDTR))
throw("ERROR: clearing DTR");
Sleep(200);
if(!EscapeCommFunction(commHandle, SETDTR))
throw("ERROR: setting DTR");
}
if(testOnStartup) {
DWORD numWritten;
char init[] = "PJON-python init";
if(!WriteFile(commHandle, init, sizeof(init), &numWritten, NULL))
throw("writing initial data to port failed");
if(numWritten != sizeof(init))
throw("ERROR: not all test data written to port");
}
};
Serial::~Serial() {
CloseHandle(commHandle);
};
// and there is more etc .......
// .............
Next question, what will actually happen in memory when executing this code and it calls the destructor? I am not able to execute it and debug it.
This code is ugly but legal. When an exception is thrown from constructor, the corresponding destructor is never called. So calling it manually before throwing is needed to prevent the resource leak. The real bug here is not calling destructor manually in other cases before throwing exception.
Of course, a better way of doing this is having a separate RAII object that encapsulates commHandle. A unique_ptr with custom deleter can serve this role.
Any destructor beyond low-level libraries is a code smell in modern C++.
Well, let's start by saying the obvious: don't write code this way. I can see why they did it - calling the destructor manually was a convenient way to clean up before throwing that exception, but why is it such a bad idea?
Well, the destructor is normally only called if the constructor runs to completion (so it won't be run, in the normal way of things, if the constructor throws) and this is deliberate as it allows the destructor to assume that the object has been fully initialised. A destructor of any complexity that tries to tear down an object which is not fully initialised is likely to run into trouble.
Now none of this matters in the code as written, because all we have here is a tinpot destructor that just closes the handle so, here, the code does correctly clean up before throwing (sometimes, thank you Eugene) and we can all sit down and relax. But as a programming pattern it stinks, and, now that you know what it actually does you should tidy it up when you move it to Delphi.
So, lecture over, a few specifics (in no particular order):
When you call a destructor manually, it's just like calling any other function - it is executed and it returns and life goes on. Specifically, the object itself is not deallocated. Doing this has value when using placement new.
It follows from the above that that call to throw will be executed after the destructor returns (it would be anyway, regardless).
Just to repeat, when a constructor throws, the destructor is not called. The object will be deallocated subsequently however, before the exception is caught (if it ever is), I believe.
If the rest of the code you have to convert is written in such a slapdash manner, I don't envy you. Constructors shouldn't fail anyway, in the general run of things, just open the port in a separate method once the object is up and running.
When you throw from the constructor, it will call the destructor of any object constructed so far: the member variables and the inherited classes (section 15.2/2).
An object of any storage duration whose initialization or destruction is terminated by an exception will have destructors executed for all of its fully constructed subobjects
If you call the destructor manually, their destructor will be also called (section 12.4/8).
After executing the body of the destructor and destroying any automatic objects allocated within the body, a
destructor for class X calls the destructors for X’s direct non-variant non-static data members, the destructors
for X’s direct base classes ...
Therefore the destructor of member variables will be called twice. Formally, calling twice a destructor is undefined behavior. (You may get away with it if they all had empty destructor.)
If you really need a clean solution, wrap the parts that need to be cleaned into a class and make it a member variable. Call the initialisation from it and if you throw, you are guaranteed that it will be cleaned.
You even get kudo points for applying RAII.

Pass an object to another thread with AfxBeginThread

My program has a callback function which is called to handle notifications that are received in the form of objects. Because we can handle hundreds a second, this callback function handles the events by spawning a separate thread to handle each one. This is the callback function:
void _OnEvent(LPCTSTR eventID, CNotification cNotificaton) {
if (_pActiveDoc) {
Param_Event* p = new Param_Event;
p->pDoc = _pActiveDoc;
p->lpszEventID = eventID;
p->cNotification = cNotification;
AfxBeginThread(ProcessEvent,p);
}
}
My query comes from the fact that is passed to the callback method is initially created on the stack, and is therefore (according to my understanding) limited to the scope of the calling method:
void CallingMethod(CString strEventID) {
CNotification cNotification;
// Fill in the details of the notification
_OnEvent(strEventID,cNotification);
}
CNotification has a full copy constructor, and since the Param_Event object is created on the heap, my belief was that this would allow the original CNotification object to fall out of scope safely, with the spawned thread working from its own "private" CNotification object that exists until the Param_Event object is deleted with delete. The fact is, however, that we are getting (rare but occasional) crashing, and I am wondering if perhaps my belief here is incorrect: is it possible that the spawned thread is still accessing the original object somehow? If this was the case, this would explain the crashing by the rare occurrence of the object both falling out of scope and being overwritten in memory, thus creating a memory access exception.
Could I be right? Is there anything actually wrong with the method I am using? Would it be safer create the notification object on the heap initially (this would mean changing a lot of our code), or building a new object on the heap to pass to the spawned thread?
For reference, here is my ProcessEvent() method:
Param_TelephoneEvent *p = (Param_TelephoneEvent*)lParam;
p->pDoc->OnTelephoneEvent(p->lpszEventID,p->cNotification);
delete p;
return 0;
All advice welcome. Thanks in advance!
Edit: Copy constructor:
CNotification& CNotification::operator=(const CNotification &rhs)
{
m_eamspeMostRecentEvent = rhs.m_eamspeMostRecentEvent;
m_eamtcsCallStatusAtEvent = rhs.m_eamtcsCallStatusAtEvent;
m_bInbound = rhs.m_bInbound;
strcpy(m_tcExtension , rhs.m_tcExtension);
strcpy(m_tcNumber, rhs.m_tcNumber);
strcpy(m_tcName,rhs.m_tcName);
strcpy(m_tcDDI,rhs.m_tcDDI);
strcpy(m_tcCallID,rhs.m_tcCallID);
strcpy(m_tcInterTelEvent,rhs.m_tcInterTelEvent);
m_dTimestamp = rhs.m_dTimestamp;
m_dStartTime = rhs.m_dStartTime;
m_nCallID = rhs.m_nCallID;
return *this;
}

Handling of LPWSAOVERLAPPED after WSASend

I am currently writing a winsock server-side socket in managed C++. After creating the LPWSAOVERLAPPED object and passing it to the WSASend function, I do not see where to delete it when the operation completes nonblocking (WSASend returns SOCKET_ERROR and WSAGetLastError() returns WSA_IO_PENDING). My current solution was to create a System::Threading::WaitHandle, get the unsafe pointer to the wait handle and pass that onto hEvent under the LPWSAOVERLAPPED object. However, this is causing unnessecary object creation since I do not really care about when the send operation is completed. On the other hand, I need a LPWSAOVERLAPPED object in order to make the operation complete non-blocking. Does anyone have any better solution to solve this? Here is my current code:
void Connectivity::ConnectionInformation::SendData(unsigned char data[], const int length)
{
if (isClosed || sendError)
return;
Monitor::Enter(this->sendSyncRoot);
try
{
LPWSAOVERLAPPED overlapped = OverlappedObjectPool::GetOverlapped();
WaitHandle ^ handle = gcnew ManualResetEvent(false);
IntPtr handlePointer = handle->SafeWaitHandle->DangerousGetHandle();
sendInfo->buf = (char*)data;
sendInfo->len = length;
overlapped->Internal = 0;
overlapped->InternalHigh = 0;
overlapped->Offset = 0;
overlapped->OffsetHigh = 0;
overlapped->Pointer = 0;
overlapped->hEvent = (void*)handlePointer; //Set pointer
if (WSASend(connection, sendInfo, 1, NULL, 0, overlapped, NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() == WSA_IO_PENDING)
{
ThreadPool::UnsafeRegisterWaitForSingleObject(handle, sentCallback, (IntPtr)((void*)overlapped), -1, true);
}
else
{
this->sendError = true;
//The send error bool makes sure that the close function doesn't get called
//during packet processing which could lead to a lot of null reffernce exceptions.
OverlappedObjectPool::GiveObject(overlapped);
}
}
else
{
handle->Close();
sentData((IntPtr)((void*)overlapped), false);
}
}
finally
{
Monitor::Exit(this->sendSyncRoot);
}
}
For async I/O, completion is notified either by the calling of a completion routine or by the queueing of an IOCP completion message to an IOCP completion queue. In both cases, it should be noted that the OVL struct should have the lifetime of at least the entire async operation, but can be longer if convenient:)
In the case of a completion routine, the unused hEvent parameter in the OVL can be used to transfer a pointer to an 'IOrequest' class instance that contains the data buffer/s, WSABUF array and the OVL struct as members, (and surely a pointer to the socket object for which the I/O has been issued). The OVL pointer is supplied as a parameter to the completion routine and so the hEvent can be retrieved and cast to the class type, so retrieving the complete class instance - OVL, data buffer etc. When the data has been processed, (or immediately in the completion routine the case of WSASend), and this IOrequest is eventually destroyed, (or repooled), the OVL will go with it. This sounds a bit incestuous, but works fine and does not need any nasty macro or other tricks.
A similar approach can be used with full IOCP or, alternatively, the OVL passed as the lpCompletionKey 'spare' parameter.
Oh - and you do care if the operation is completed - you need to at least check for errors.

Under what conditions is CCmdTarget::OnFinalRelease called?

The MSDN documentation for the CCmdTarget::OnFinalRelease method is pretty brief:
Called by the framework when the last OLE reference to or from the
object is released.
I have created a sub-class of CCmdTarget
class CMyEventHandler : public CCmdTarget { ... }
I'm trying to figure out under what conditions the OnFinalRelease method will be called. I have some code that looks something like this:
CMyEventHandler* myEventHandler = new CMyEventHandler();
LPUNKNOWN pUnk = myEventHandler->GetIDispatch(FALSE);
AfxConnectionAdvise(myEventSource, DIID_IMyEventInterface, pUnk, FALSE, myCookie);
// Application continues...events arrive...eventually the event sink is shutdown
LPUNKNOWN pUnk = myEventHandler->GetIDispatch(FALSE);
AfxConnectionUnadvise(myEventSource, DIID_IMyEventInterface, pUnk, FALSE, myCookie);
Using this code, I observe that the OnFinalRelease method is never called. This means I have a memory leak. So I modified the wrap-up code as follows:
LPUNKNOWN pUnk = myEventHandler->GetIDispatch(FALSE);
AfxConnectionUnadvise(myEventSource, DIID_IMyEventInterface, pUnk, FALSE, myCookie);
delete myEventHandler;
myEventHandler = NULL;
This section of code is triggered off periodically throughout the day. What I notice now is that, while the destructor for the wrapped up instance of myEventHandler is called as expected, the OnFinalRelease function is getting called now! What's worse, it is being called not on the instance that has been wrapped up, but instead on a newly created instance of CMyEventHandler! Thinking that this might be due to a reference counting issue, I modified my wire-up and wrap-up code:
CMyEventHandler* myEventHandler = new CMyEventHandler();
LPUNKNOWN pUnk = myEventHandler->GetIDispatch(TRUE);
AfxConnectionAdvise(myEventSource, DIID_IMyEventInterface, pUnk, TRUE, myCookie);
pUnk->Release();
// Application continues...events arrive...eventually the event sink is shutdown
LPUNKNOWN pUnk = myEventHandler->GetIDispatch(TRUE);
AfxConnectionUnadvise(myEventSource, DIID_IMyEventInterface, pUnk, TRUE, myCookie);
pUnk->Release();
delete myEventHandler;
myEventHandler = NULL;
I let this run all day and now observe that OnFinalRelease is never called. The destructor for the wrapped up instance is called as I would expect, but I'm left feeling uneasy as I clearly don't understand the circumstances under which OnFinalRelease is called. Is OnFinalRelease called on some delay, or is there a way to force it to fire? What will trigger OnFinalRelease to be called?
If it matters, the event source is a .NET assembly exposing events via COM interop.
With COM you should always use the CoCreateInstance() AddRef() and Release() paradigm to manage lifetime of your objects, and let COM do the destruction of your objects based on reference counts. Avoid new and delete because using them breaks this paradigm and causes interesting side effects. You probably have a bug in the management of the reference counts.
The way to debug why the reference counts are not being managed correctly is to override CCmdTarget::InternalRelease() copy the source from oleunk.cpp and put some trace output or break points.
DWORD CMyEventHandler::InternalRelease()
{
ASSERT(GetInterfaceMap() != NULL);
if (m_dwRef == 0)
return 0;
LONG lResult = InterlockedDecrement(&m_dwRef);
if (lResult == 0)
{
AFX_MANAGE_STATE(m_pModuleState);
OnFinalRelease();
}
return lResult;
}
There are lots of times when passing IDispatch interfaces that code will bump reference counts and you have to decrement the reference count using Release(). Pay attention to where your code may be passing this interface because there is aconvention in COM that when Interfaces are passed using [in] or [out] where the caller or callee has to release the interface.
When the reference count issue is corrected you shoudl see the objects OnFinalRelease code being called and the object destoryed by hte MFC framework:
For CCmdTarget the destruction should happen as a result of the final
release in the parent class CWnd:
void CWnd::OnFinalRelease()
{
if (m_hWnd != NULL)
DestroyWindow(); // will call PostNcDestroy
else
PostNcDestroy();
}
FYI: Passing interfaces across threads without marshalling the interface pointers is another common reason to get errors in COM.
It doesn't appear that you ever call myEventHandler->Release(). Therefore, the last reference is never released, and OnFinalRelease is never called.