I have some statics I use to check if a thread is running, and if the program wants to / can close.
Normally I would create a seperate function for each variable like so:
static CCriticalSection crit_sec;
static bool static_thread_a_closed = false;
static bool static_thread_b_closed = false;
static bool static_prog_closing = false;
static void Set_thread_a_Val(bool set_to)
{
crit_sec.Lock();
static_thread_a_closed = set_to;
crit_sec.Unlock();
};
static bool Get_thread_a_Val()
{
bool ret;
crit_sec.Lock();
ret = static_thread_a_closed;
crit_sec.Unlock();
return ret;
};
// etc etc for the others...
void thread_a::Do()
{
//code
Set_thread_a_Val(false);
}
void MainDlg::OnClose()
{
//code..
while(Get_thread_a_Val()) // ... wait
//code..
}
I am wondering if it would be 'safe' to do this with pointers like so:
static CCriticalSection crit_sec;
static bool static_thread_a_closed = false;
static bool static_thread_b_closed = false;
static bool static_prog_closing = false;
static void Set_Bool_Val(bool* val, bool set_to)
{
crit_sec.Lock();
*val = set_to;
crit_sec.Unlock();
};
static bool Get_Bool_Val(bool* val)
{
bool ret;
crit_sec.Lock();
ret = *val;
crit_sec.Unlock();
return ret;
};
void thread_a::Do()
{
//code
Set_Bool_Val(&static_thread_a_closed, false);
}
void MainDlg::OnClose()
{
//code..
while(Get_Bool_Val(&static_thread_a_closed)) // ... wait
//code..
}
Is the memory actually accessed when it is passed, so this will fail?
Or is it simply pass the address, meaning this would be ok?
The pointers are fine.
However, there is a good chance that static_thread_a_closed will not be read a second time because C doesn't, by default, know that static_thread_a_closed can change in the while loop.
Adding volatile keywords lets the compiler know that variables can be changed by interrupts/other threads/other processes, so that the variable must always be re-read. Otherwise, your while() might be optimized to while(1) or while(0).
static volatile bool static_thread_a_closed = false;
static volatile bool static_thread_b_closed = false;
static volatile bool static_prog_closing = false;
static bool Get_Bool_Val(volatile bool* val)
Edit: After realizing I triggered some "Volatile Hostility," I should add that in this case, the volatiles will probably not make any difference in either case. In both cases, the while() is based on the return value of a function which the compiler should not optimize out, regardless if it wants to use the cached value of the static flags.