Re: WaitForSingleObject
Larry wrote:
map<int, circular> users;
CRITICAL_SECTION users_mutex;
map<int, HANDLE> eventi;
CRITICAL_SECTION eventi_mutex;
This looks much better, it makes the association immediately clear.
EnterCriticalSection(&eventi_mutex);
eventi.insert(make_pair(threadid,hevent));
LeaveCriticalSection(&eventi_mutex);
Access to 'eventi' guarded in critical section, correct.
BTW: You can also write
eventi[threadid] = hevent;
// CALLBACK EVENT
WaitForSingleObject(eventi[threadid], INFINITE);
Wait:
1. Access to 'eventi' is not inside a critical section.
2. You could simply use 'hevent'.
if(users[threadid].cb.at(0).flag == BUFF_DONE)
{
string line = (char*)users[threadid].cb.at(0).data;
Similarly, access to 'users' is not guarded here!
// Close & remove event from event map
CloseHandle(eventi[threadid]);
EnterCriticalSection(&eventi_mutex);
eventi.erase(threadid);
LeaveCriticalSection(&eventi_mutex);
Imagine the producer creating some content, then the consumer destroys the
event object, then the producer tries to signal the event.
EnterCriticalSection(&eventi_mutex);
eventi.erase(threadid);
LeaveCriticalSection(&eventi_mutex);
CloseHandle(hevent);
EnterCriticalSection(&users_mutex);
EnterCriticalSection(&eventi_mutex);
Here is one possible problem, which is called "deadlock". Imagine one thread
locking 'users_mutex' and another locking 'eventi_mutex'. Now, both threads
try to lock the other mutex. Neither thread will ever get the lock. Mihajlo
mentioned that you shouldn't sleep with a lock held. Actually, you also
shouldn't try to acquire another lock with a lock already held!
There is one easy fix: Create a single map from thread-ID to the shared
structure of both threads. The shared structure contains both the IO
buffers and the event to wake up the consumer. The consumer is also
responsible for creating the entry when it's ready and removing it when
finished.
Uli
--
C++ FAQ: http://parashift.com/c++-faq-lite
Sator Laser GmbH
Gesch??ftsf??hrer: Thorsten F??cking, Amtsgericht Hamburg HR B62 932