|
Here is sample code. Please help
void DSReadableConnectionThread::RemoveConnection( const DSReadableConnection &connection )
{
pReadList->Request(); /*Request()calls ::EnterCriticalSection().This works in windows xp and below versions of OS. But it is not working on Vista. It contineously wait at EnterCriticalSection().
pNewConnectionList>Request();*/
if( !pReadList->Remove(connection) )
{
pNewConnectionList->Remove( connection );
}
// If no connections to process then put ThreadMain() to sleep
if( pReadList->isEmpty()&& pNewConnectionList->isEmpty() )
{
ready.ClearSignal();
}
pNewConnectionList->Release();
pReadList->Release();
}
|
|
|
|
|
The only way this can happen is if another thread is already "in" the
critical section. But that wouldn't work on any OS.
If you can put together a project that builds and fails that will run on
my machine, I can take a look. Otherwise it's really hard to debug from here
There's still no relevant code I've seen. Is the critical section initialized properly
before any thread tries to enter it?
Are you positive it's deadlocking at the EnterCriticalSection?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I checked it again. Initialization of critical section is properly done.
Here is actual code goes..
inline void Request() const
{
EnterCriticalSection( &_section ); //Here actually it stuck on Vista.
::InterlockedIncrement(&m_nLockCount);
}
If some other thread is using this crititcal section,it shouldn't have worked on any other os also.But it is working perfectly except on Vista.
Is there any change on Vista architecture in threading and synchronization. Something is mentioned in this link: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=510229&SiteID=1
Do you have any idea on this?
|
|
|
|
|
The only difference in Vista is the threading is more efficient.
The changes can expose problems in improperly written threading code
(not as many problems as multi-core machines expose ).
You've got some kind of deadlock. Maybe put TRACE statements before
and after EVERY enter/leave of the critical section and see if you can find
it. I don't know what else to say except you need to debug it.
Why the InterlockedIncrement() call? What is the critical section protecting?
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi...
I have checked it again. I don’t think there is any deadlock present. There is no resource as such on which more than 1 threads are waiting.
LockCount - RecursionCount = Number of waiting threads
In my case, Number of waiting threads = 0.
But I found one more interesting thing on vista. WaitForSingleObject() is used here. When I called this function with TIMEOUT=INFINITE. It is not coming out of loop at all. It will be looping there. On Vista WaitForSingleObject() returns 258(I guess it is=WAIT_TIMEOUT). But on XP and lower versions of OS this function returns 0(I guess it is=WAIT_OBJECT_0) and come out of the of the loop.Please see the below code.
bool DSEventSemaphore::WaitForSignal( DWORD TimeOut ) //TimeOut=INFINITE
{
if( State == SemInvalid )
{
return false;
}
DWORD retval;
#ifndef DSTRACEABLE_SIGNAL_STACK /*I haven't defined it. So it wiil not execute.*/
retval = WaitForSingleObject( event, TimeOut );
#else //It will come here
do
{ retval = WaitForSingleObject( event, (TimeOut< DSSLEEP_PERIOD ? TimeOut : DSSLEEP_PERIOD) ); //DSSLEEP_PERIOD=500
if( retval == WAIT_TIMEOUT )
{
if( TimeOut < DSSLEEP_PERIOD )
{
TimeOut = 0;
}
else
if( TimeOut != INFINITE )
{
TimeOut -= DSSLEEP_PERIOD;
}
}
else
{
TimeOut = 0;
}
} while( TimeOut );
#endif
switch (retval)
{
case WAIT_OBJECT_0:
State = SemOK;
return true;
case WAIT_TIMEOUT:
State = SemTimeOut;
Error = GetLastError();
return false;
case WAIT_FAILED:
default:
Error = GetLastError();
State = SemSystemError;
return false;
}
}
Could you please help me.
|
|
|
|
|
Forget about the difference between XP and Vista. It's not relevant
at all. The same threading rules apply as always. Vista can be much
more efficient at exposing faulty threading code. If it works on one
OS and not on another, then it DOESN'T WORK. I've found bugs YEARS
after I wrote the code that suddenly fail on a new OS. Also moving
from single core to multi-core machines can expose threading bugs.
Back to your code...
If WaitForSingleObject(INFINITE) is blocking forever, then the handle
is never getting signaled. It's that simple.
What code is responsible for signaling the event?
(FWIW, "event" is a keyword in C++ - you may not want to use that as a variable name )
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi mark,
Finaly I am able resolve the issue.This issue is a classical example of starvation. The critical section is held by thread and is being released and requested again immediately in a tight while loop. This never allows other threads to acquire the critical section. But it is working on xp OS. This was leading to starvation on vista for the thread/threads waiting on that critical section. I have used the SwitchToThread() API call( sleep() also serve the purpose).But I found SwitchToThread() is better option. Looks like threading model on Vista is more efficient.
thanks for your help.
|
|
|
|
|
It's "stuck" because that critical section is being used by another thread!
One possibility is that an exception is being thrown over the release.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
Is there anyway to know which thread is using critical section?
|
|
|
|
|
No. You could set breakpoints on the Enter and Leave and start counting (yeah, been there.)
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
Actually there is. See here[^].
Steve
|
|
|
|
|
Yes there is. Use the !critsec command in WinDBG[^].
Steve
|
|
|
|
|
Thanks. This is much helpful.
|
|
|
|
|
Hi...
I have checked it again. I don’t think there is any deadlock present. There is no resource as such on which more than 1 threads are waiting.
LockCount - RecursionCount = Number of waiting threads
In my case, Number of waiting threads = 0.
But I found one more interesting thing on vista. WaitForSingleObject() is used here. When I called this function with TIMEOUT=INFINITE. It is not coming out of loop at all. It will be looping there. On Vista WaitForSingleObject() returns 258(I guess it is=WAIT_TIMEOUT). But on XP and lower versions of OS this function returns 0(I guess it is=WAIT_OBJECT_0) and come out of the of the loop.Please see the below code.
bool DSEventSemaphore::WaitForSignal( DWORD TimeOut ) //TimeOut=INFINITE
{
if( State == SemInvalid )
{
return false;
}
DWORD retval;
#ifndef DSTRACEABLE_SIGNAL_STACK /*I haven't defined it. So it wiil not execute.*/
retval = WaitForSingleObject( event, TimeOut );
#else //It will come here
do
{ retval = WaitForSingleObject( event, (TimeOut< DSSLEEP_PERIOD ? TimeOut : DSSLEEP_PERIOD) ); //DSSLEEP_PERIOD=500
if( retval == WAIT_TIMEOUT )
{
if( TimeOut < DSSLEEP_PERIOD )
{
TimeOut = 0;
}
else
if( TimeOut != INFINITE )
{
TimeOut -= DSSLEEP_PERIOD;
}
}
else
{
TimeOut = 0;
}
} while( TimeOut );
#endif
switch (retval)
{
case WAIT_OBJECT_0:
State = SemOK;
return true;
case WAIT_TIMEOUT:
State = SemTimeOut;
Error = GetLastError();
return false;
case WAIT_FAILED:
default:
Error = GetLastError();
State = SemSystemError;
return false;
}
}
Could you please help me.
|
|
|
|
|
I hate to say this, but you have me stumped. Have you verified this on another Vista install? Is your software running in a separate user account? (Like, as a service.) You could write a small program with two threads that does nothing but waits using various mechanisms.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
i hav two projects made in VC 6 and i want to combine them into a single application
it may hav common variables or structures
bt they should be made global
can ne1 help?
|
|
|
|
|
There's no magic way for doing that: you'll have to copy and paste part of the code you want to reuse in your new application. That's probably not an easy task...
|
|
|
|
|
|
|
You have the source code - use it!
I guarantee the info you find there will be more (or at least as) accurate than any response here.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
When I use TryEnterCriticalSection() I am getting an error as TryEnterCriticalSection' : undeclared identifier. I have included #define _WIN32_WINNT 0x0500 and windows.h in my header file. How can solve this problem?
Thanks in advance.
|
|
|
|
|
Possibly you need an updated Platform SDK .
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
I tried this on Windows XP and Vista as well.
|
|
|
|
|
My point wasn't about the OS it was about the installed SDK . As the name implies, the SDK is a development tool, it doesn't come together with the OS , you need to download it from the Microsoft website.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Thanks. I am able to compile it without any error now. I have incuded the definition _WIN32_WINNT=0x0502 in project settings instead of in the header file.
|
|
|
|