Re: STL vector and multithreading
Igor here is the code you requested
For adding the callback to the vector:
STDMETHODIMP CHW::Advise(ICallback* pcallback, long nPriority, long* pCookie)
{
HRESULT hr = S_OK;
DWORD dwWaitResult = WaitForSingleObject(m_hMutex, 5000L);
switch (dwWaitResult) {
// The thread got mutex ownership.
case WAIT_OBJECT_0:
CCallBackItem* cbi;
cbi = new CCallBackItem(nPriority, pcallback);
*pCookie = (long)cbi;
cbi->m_nCookie = *pCookie;
m_vecAdvise.push_back(cbi);
std::sort(m_vecAdvise.begin(), m_vecAdvise.end(), SortPriority);
ATLTRACE("advised\n");
break;
case WAIT_TIMEOUT:
case WAIT_ABANDONED:
default:
hr = E_FAIL;
break;
}
if (SUCCEEDED(hr) && !ReleaseMutex(m_hMutex)) // release mutex
hr = E_FAIL;
return hr;
}
For changing the priority of an existing item
STDMETHODIMP CHW::SetPriority(LONG nCookie, LONG nPriority)
{
// TODO: Add your implementation code here
HRESULT hr = S_OK;
DWORD dwWaitResult = WaitForSingleObject(m_hMutex, 5000L);
switch (dwWaitResult)
{
case WAIT_OBJECT_0:
{
vector <CCallBackItem*>::iterator iter;
for (iter = m_vecAdvise.begin(); iter < m_vecAdvise.end(); iter++) {
if ((*iter)->m_nCookie == nCookie) {
(*iter)->m_nPriority = nPriority;
ATLTRACE("New priority set\n");
break;
}
}
std::sort(m_vecAdvise.begin(), m_vecAdvise.end(), SortPriority);
}
break;
case WAIT_TIMEOUT:
case WAIT_ABANDONED:
default:
hr = E_FAIL;
}
if (SUCCEEDED(hr) && !ReleaseMutex(m_hMutex))
hr = E_FAIL;
return hr;
}
And finally here is the code that runs in the worker thread that iterates
and does
the callbacks
HRESULT hr = S_OK;
DWORD dwWaitResult = WaitForSingleObject(h_hMutex, 5000L);
switch (dwWaitResult)
{
case WAIT_OBJECT_0:
{
vector < CCallBackItem *>::iterator iter;
for (iter = m_vecAdvise.begin(); iter < m_vecAdvise.end(); iter++)
(*iter)->m_pCallbackFunc->CallbackFunc();
}
break;
case WAIT_TIMEOUT:
case WAIT_ABANDONED:
default:
hr = E_FAIL;
break;
}
if (SUCCEEDED(hr) && !ReleaseMutex(m_hMutex)) // release mutex
hr = E_FAIL;
// do something with hr
Now after looking at this code there could be a problem with using the
address of the created object as the cookie, this could result in duplicates.
"Igor Tandetnik" wrote:
John <John@discussions.microsoft.com> wrote:
I have created a STL vector of callback functions that also allows the
programmer to specify a priority on which to be "called back". In my
main thread, routines exist to add callbacks (advise), remove
callbacks (unadvise) and change the priority level of an existing
callback, through the use of a cookie. After each access of the
vector I perform a sort on the specified priority level. All the
routines have been encapsulated by a mutex object.
Now in a worker thread I access this vector (using the same mutex)
iterate through the items and perform the callbacks on receipt of an
event from some hardware.
Now here is the problem, I am getting memory access errors and
occasionally mutex timeouts when I try to access the vector from
different locations in my program.
Show some code. You are doing something wrong. Specifically, you have
code that manipulates the vector outside of mutex protection.
Do you, by any chance, store iterators or pointers to elements of the
vector? You mention a cookie - what precisely is it? Also show the code
that iterates over the contents of the vector and performs the
callbacks - including mutex locks and unlocks.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925