In c++, MFC:
I have a CComPointer:
CComPointer<IMyTask> m_pTask;
there are a lot of places in my code, I call to this ComPointer to run the task's methods. For example:
void method1()
{
if (FAILED(hRet = m_pTask->MyFunc1()))
.....
}
void method2()
{
if (FAILED(hRet = m_pTask->MyFunc2()))
.....
}
I try to solve a problem to recover when MyTask is down. I wrote a method, recover(), that rerun the CoCreate to MyTask, and it actually solves the problem.
I could see that if MyTask is dead, i get an HR fail code of -2147023174, RPC server is unavailable. But, the com pointer m_pTask has the full data (it doesn't know the task is dead).
I can do something like this:
void method1()
{
if (FAILED(hRet = m_pTask->MyFunc1()))
if (hRet == -2147023174)
recover();
.....
}
void method2()
{
if (FAILED(hRet = m_pTask->MyFunc2()))
if (hRet == -2147023174)
recover();
.....
}
But, because I have alot of calling to methods via the compointer, I want to make something more general. I want that everytime I try to run a method via the ComPointer, before the runnuing of the method, to check that the task is already exists, and if not - run the recover method. Since even when the task is dead, ComPointer still has all the data from the CoCreate time, I don't know how can I do it.
How can I do it?
The task is dead due to an error that occurs sometiems in the system, and for now my solution does not need to find the reason for the task failure, just to recover it. I am looking for a general solution - like a wrapper to the ComPointer, but I want that the wrapper class will only check if MyTask is still exists, and if it is -it will return the ComPointer, and if not, it will run recover.
How can I do it?
Okay, it's a general answer to a general question. I don't want to know, why the task is actually dead, when the pointer is not. Write a wrapper for the task pointer and use it instead. It will look something like this:
class CMyTaskWrapper
{
CComPtr<IMyTask> m_ptr;
...
HRESULT myFunc1()
{
HRESULT hRes = m_ptr->myFunc1();
if(hRes == 0x800706BA)
{
recover();
}
return hRes;
}
... //here you should list all members of IMyTask
};
Edit1: added a macros sample (see comment #2)
MYMACRO_0(HRESULT_GETTER, POINTER, FUNCTION) \
HRESULT_GETTER = POINTER->FUNCTION(); \
if(HRESULT_GETTER == 0x800706BA) recover(); \
HRESULT_GETTER = POINTER->FUNCTION()
MYMACRO_1(HRESULT_GETTER, POINTER, FUNCTION, PARAM1) \
HRESULT_GETTER = POINTER->FUNCTION(PARAM1); \
if(HRESULT_GETTER == 0x800706BA) recover(); \
HRESULT_GETTER = POINTER->FUNCTION(PARAM1)
//here you should add MYMACRO_2 ... MYMACRO_N
You can use it in following way:
MYMACRO_0(hRes, m_pTask, MyFunc1);
MYMACRO_1(hRes, m_pTask, MyFunc2, parameter_to_pass);
This could help, and this will hide the function list, but nevertheless it's not very good idea to use such code.