What happens to a FS Plugin when i exit TC?
Moderators: Hacker, petermad, Stefan2, white
What happens to a FS Plugin when i exit TC?
Hi,
In my FS plugin i have a thread a thread for logging which is cleaned in the main class destructor.
What is bugging me is that sometimes (when i quit TC) it seems that i'm getting a deadlock, because the logging thread does not show any activity, and TC window frame becomes white as if it wasn't processing any messages, or waiting for something else.
But if i disable the logging thread the symptom is gone.
I am unable to debug this problem.
Any hint?
In my FS plugin i have a thread a thread for logging which is cleaned in the main class destructor.
What is bugging me is that sometimes (when i quit TC) it seems that i'm getting a deadlock, because the logging thread does not show any activity, and TC window frame becomes white as if it wasn't processing any messages, or waiting for something else.
But if i disable the logging thread the symptom is gone.
I am unable to debug this problem.
Any hint?
______________________
David Jorge
Personal License #117854
David Jorge
Personal License #117854
You may terminate this thread or to change some global variable so thread will exit itself - you should do this during call to DllMain with fdwReason=DLL_PROCESS_DETACH.
E.g. in my VirtualPanel plugin I have configuration dialog that runs in separate thread to allow using TC while its open - so I send to that window exit message and wait until it is closed before returning from DllMain. Also I stop all timers in DllMain and wait until its process functions finish work (they run also in separate threads).
E.g. in my VirtualPanel plugin I have configuration dialog that runs in separate thread to allow using TC while its open - so I send to that window exit message and wait until it is closed before returning from DllMain. Also I stop all timers in DllMain and wait until its process functions finish work (they run also in separate threads).
The problem is that my dll is a MFC dll and i'm getting some errors saying that DllMain is already defined. Even trying this http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/d86b96a2-a5c9-4bfc-98e1-61b55e50ecae is not compiling...
______________________
David Jorge
Personal License #117854
David Jorge
Personal License #117854
If you're using MFC, perhaps you should insert finalization code into another place - according to MFC principles. Just refer to MSDN MFC documentation.
Now I created MFC DLL project (I called it MFCDLL), it made some files for me, I read the TODO comments and I see that I should put initialization code into CMFCDLLApp::CMFCDLLApp() function (i.e. class constructor). It is logical that I should put finalization code into that class's destructor - just need to add it into a class's interface and write code. So, initialization code you should put into CMFCDLLApp::CMFCDLLApp() function instead of DllMain, and finalization code - into CMFCDLLApp::~CMFCDLLApp() function instead of DllMain.
E.g. I have default predefined class in <project_name>.h file:
And constructor's realization in <project_name>.cpp:
I need to add destructor into a class:
And its realization e.g. below constructor's realization:
Now when I'm loading DLL, hello message appears, and when I'm unloading it, bye message appears!
But if you read comment for constructor, you will see recommendation to place significant initialization in InitInstance. According to MSDN there is a function ExitInstance that is called for finalization, you just need to define it:
And its code e.g. just below InitInstance's code:
Now when DLL is loading, I see hello message, then hey message - constructor and InitInstance are called, then my DLL is ready to work. When it is terminated, I see sorry message and then bye message - ExitInstance and destructor are called.
So, you may terminate your background threads in ExitInstance function, or in destructor - you have a choice.
Don't forget that your main class is destroyed after call to destructor, so if your background threads still active, they may try to access to destroyed objects - effect is unpredictable!
Now I created MFC DLL project (I called it MFCDLL), it made some files for me, I read the TODO comments and I see that I should put initialization code into CMFCDLLApp::CMFCDLLApp() function (i.e. class constructor). It is logical that I should put finalization code into that class's destructor - just need to add it into a class's interface and write code. So, initialization code you should put into CMFCDLLApp::CMFCDLLApp() function instead of DllMain, and finalization code - into CMFCDLLApp::~CMFCDLLApp() function instead of DllMain.
E.g. I have default predefined class in <project_name>.h file:
Code: Select all
class C<project_name>App : public CWinApp
{
public:
C<project_name>App();
// Overrides
public:
virtual BOOL InitInstance();
DECLARE_MESSAGE_MAP()
};
Code: Select all
C<project_name>App::C<project_name>App()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
MessageBox(0, L"Hello, I'm initialized!", L"C<project_name>App::C<project_name>App()", 0);
}
Code: Select all
class C<project_name>App : public CWinApp
{
public:
C<project_name>App();
~C<project_name>App(); // destructor
// Overrides
public:
virtual BOOL InitInstance();
DECLARE_MESSAGE_MAP()
};
Code: Select all
C<project_name>App::C<project_name>App()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
MessageBox(0, L"Hello, I'm initialized!", L"C<project_name>App::C<project_name>App()", 0);
}
C<project_name>App::~C<project_name>App()
{
MessageBox(0, L"Bye, I'm finalized!", L"C<project_name>App::~C<project_name>App()", 0);
}
But if you read comment for constructor, you will see recommendation to place significant initialization in InitInstance. According to MSDN there is a function ExitInstance that is called for finalization, you just need to define it:
Code: Select all
class C<project_name>App : public CWinApp
{
public:
C<project_name>App();
~C<project_name>App(); // destructor
// Overrides
public:
virtual BOOL InitInstance();
virtual int ExitInstance(); // exit instance function
DECLARE_MESSAGE_MAP()
};
Code: Select all
BOOL CMFCDLLApp::InitInstance()
{
CWinApp::InitInstance(); // call to base class function - don't remove it
MessageBox(0, L"Hey, I'm significantly initialized!", L"BOOL CMFCDLLApp::InitInstance()", 0);
return TRUE;
}
int CMFCDLLApp::ExitInstance()
{
MessageBox(0, L"Sorry, I'm finalized!", L"int CMFCDLLApp::ExitInstance()", 0);
return CWinApp::ExitInstance(); // call to base class function - don't remove it
}
So, you may terminate your background threads in ExitInstance function, or in destructor - you have a choice.

Don't forget that your main class is destroyed after call to destructor, so if your background threads still active, they may try to access to destroyed objects - effect is unpredictable!