I`m writing a chat using WinSock2 and WinAPI functions. And I have a little trouble.
I store the std::vector of client connections on server. When new client connects, new thread starts and all work with the client is done in this new thread. I do not use classes (I know it is not very good) so this list of connections is just defined as global variable.
It seems to me that it can be a situation when several threads try to access this list simultaneously. Though I have not noticed that there are any problems with that, do I need to do something like this:
template
class SharedVector {
std::vector vect;
CRITICAL_SECTION cs;
SharedVector(const SharedVector& rhs) {}
public:
SharedVector();
explicit SharedVector(const CRITICAL_SECTION& CS);
void PushBack(const T& value);
void PopBack();
unsigned int size();
T& operator[](int index);
virtual ~SharedVector();
};
template
SharedVector::SharedVector() {
InitializeCriticalSection(&cs);
}
template
SharedVector::SharedVector(const CRITICAL_SECTION& r): cs(r) {
InitializeCriticalSection(&cs);
}
template
void SharedVector::PushBack(const T& value) {
EnterCriticalSection(&cs);
vect.push_back(value);
LeaveCriticalSection(&cs);
}
template
void SharedVector::PopBack() {
EnterCriticalSection(&cs);
vect.pop_back();
LeaveCriticalSection(&cs);
}
So, does my situation require using CRITICAL_SECTION and am I just the lucky guy who did not find a mistake?
Yes, you are just lucky never to experience any problems. This is the problem with synchronization issues and race conditions, that the code will work in 99.9% of all cases, and when disaster strikes you won't know why.
I would take away the constructor taking a CRITICAL_SECTION as a parameter since it is not clear without looking at (presumably non-existing) documentation to realize that the constructor will initialize it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With