
For what it's worth, the version of Boost.Thread in the thread_dev branch of CVS already uses a critical section when possible. As time allows, I'm planning to review the code in the thread_dev branch, ask for comments, finish anything that isn't finished, and move it to the main branch piece by piece. I'm currently doing this (very slowly, I'm afraid) for the thread_specific_ptr and related classes. Mike Adal Chiriliuc wrote:
Hello.
try_mutex uses a Mutex instead of a CRITICAL_SECTION because on Windows 9x and Me it's impossible to try the aquisition of a CRITICAL_SECTION.
On Windows NT/2000/XP this is possible, using the function TryEnterCriticalSection.
So I suggest this: choose at runtime what syncronization primitive to use based on the running OS. CRITICAL_SECTIONS are much faster and since Windows NT is gradually replacing Windows 9x systems I think it is good to use this feature.
A sketch follows.
---------- mutex.cpp -----------
namespace { bool g_Init = false; bool g_UseTryCritical; TryCriticalProcType g_TryCritical;
void TryCriticalInit() { g_Init = true; g_UseTryCritical = false; get windows version; if (!windows nt) return; lib = load library (kernel32.dll); g_TryCritical = get proc address (lib, TryEnterCriticalSection); g_UseTryCritical = true; }
}
try_mutex::try_mutex() { if (!g_Init) TryCriticalInit(); if (g_UseTryCritical) { try { m_mutex = reinterpret_cast<void*>(new CRITICAL_SECTION); } catch (...) { } } else { m_mutex = reinterpret_cast<void*>(CreateMutex(0, 0, 0)); } if (!m_mutex) throw thread_resource_error(); if (g_UseTryCritical)
InitializeCriticalSection(reinterpret_cast<LPCRITICAL_SECTION>(m_mutex ));
}
bool try_mutex::do_trylock() { if (g_UseTryCritical) { return g_TryCritical(reinterpret_cast<LPCRITICAL_SECTION>(m_mutex)) != 0; } else { unsigned int res = 0; res = WaitForSingleObject(reinterpret_cast<HANDLE>(m_mutex), 0); assert(res != WAIT_FAILED && res != WAIT_ABANDONED); return res == WAIT_OBJECT_0; } }
---------- mutex.cpp -----------
There is only one potential problem: if (!g_Init) TryCriticalInit(); might not be thread safe.
Something like a thread safe singleton might be needed. Or maybe we could use InterlockedExchange & co.
I'm not sure if timed_mutex could also benefit from this.
In the docs you should explain what joining means. I worked a lot with threads in the past, but I've never heard of such a concept. I had to look through the source codes to understand what join means. Many Win32 developers will not know of concepts not covered by the Platform SDK. You do explain that conditions are some sort of events, but you use joining in sample code without explaining what it does.
Regards, Adal Chiriliuc
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost