Hello drh,
Like Igor, I like the critical section, the problem is that pesky
"Try" function which doesn't exist in older windows versions. The
mutex though lets you try by attempting the lock with a timeout. I'm a
little leery of the timeout in the "Try", I think it smells a bit of a
race condition.
So, if you're going to abandon 98 and ME, I'd use Igor's idea. The
critical section is faster than the mutex too.
The attached files are something I whipped out by pulling apart one of
my mutex classes. It seems too simple to get wrong but, I didn't test
them other then getting them to compile. Microsoft claims that the
Mutex is re-enterable from the same thread.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/tryentercriticalsection.asp
If the attachment doesn't work, I can embed them in an email. They're
pretty small.
C
Saturday, January 14, 2006, 9:51:46 AM, you wrote:
dhc> Teg <[EMAIL PROTECTED]> wrote:
>>
>> To me the proper solution would be to avoid using TLS in the first
>> place since, you (sqlite) neither create nor destroy the thread.
>>
dhc> I'm trying to move in this direction - to eliminate the need
dhc> for TLS entirely. But in order to do so I am going to need
dhc> some additional thread locking primitives. The standard
dhc> pthreads library on Unix provides everything I need. But
dhc> locking primitives on windows seem to be - well - more
dhc> "primitive". I'm looking for suggestions on how to implement
dhc> the features I need on windows. All hints are appreciated.
dhc> I have consulted the pthreads-win32 library (an open-source
dhc> implementaton of pthreads for windows systems.) They clearly
dhc> get all of this to work. But it is a lot of code. I'm
dhc> wondering if there isn't an easier way.
dhc> In summary, what I need is a recursive mutex. Here are the
dhc> requirements:
dhc> (1) An abstract (a.k.a opaque) type RecursiveMutex that can
dhc> be an element of a structure.
dhc> (2) Procedures InitializeRecursiveMutex() and
dhc> DestroyRecursiveMutex() used to initialize and clear
dhc> RecursiveMutex elements when they are allocated and
dhc> deallocated.
dhc> (3) Procedures EnterRecursiveMutex() and LeaveRecursiveMutex().
dhc> Only one thread at a time is allowed in a mutex, though
dhc> the same thread can enter a mutex multiple times (hence
dhc> the "recursive" in the name.) If a thread enters a mutex
dhc> multiple times, it must also leave the same number of times
dhc> before another thread can enter. A call to EnterRecursiveMutex()
dhc> will block if a different thread is already in the mutex.
dhc> Execution will resume after the other thread leaves.
dhc> (4) Procedure TryRecursiveMutex(). This is similar to
dhc> EnterRecursiveMutex() except that it does not block. If
dhc> entry into the mutex is allowed, TryRecursiveMutex() enters
dhc> the mutex and returns TRUE. If another thread is holding
dhc> the mutex, then TryRecuriveMutex() returns FALSE.
dhc> Thanks in advance for your help.
dhc> --
dhc> D. Richard Hipp <[EMAIL PROTECTED]>
--
Best regards,
Teg mailto:[EMAIL PROTECTED]
#ifdef _WIN32
void* InitializeRecursiveMutex(void);
void EnterRecursiveMutex(void* pHandle);
void LeaveRecursiveMutex(void* pHandle);
int TryEnterRecursiveMutex(void* pHandle);
void DestroyRecursiveMutex(void* pHandle);
#endif // WIN32
#include <Windows.h>
#ifdef _WIN32
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "SqliteMutex.h"
#ifdef DOCS
dhc> (1) An abstract (a.k.a opaque) type RecursiveMutex that can
dhc> be an element of a structure.
dhc> (2) Procedures InitializeRecursiveMutex() and
dhc> DestroyRecursiveMutex() used to initialize and clear
dhc> RecursiveMutex elements when they are allocated and
dhc> deallocated.
dhc> (3) Procedures EnterRecursiveMutex() and LeaveRecursiveMutex().
dhc> Only one thread at a time is allowed in a mutex, though
dhc> the same thread can enter a mutex multiple times (hence
dhc> the "recursive" in the name.) If a thread enters a mutex
dhc> multiple times, it must also leave the same number of times
dhc> before another thread can enter. A call to EnterRecursiveMutex()
dhc> will block if a different thread is already in the mutex.
dhc> Execution will resume after the other thread leaves.
dhc> (4) Procedure TryRecursiveMutex(). This is similar to
dhc> EnterRecursiveMutex() except that it does not block. If
dhc> entry into the mutex is allowed, TryRecursiveMutex() enters
dhc> the mutex and returns TRUE. If another thread is holding
dhc> the mutex, then TryRecuriveMutex() returns FALSE.
dhc> Thanks in advance for your help.
dhc> --
dhc> D. Richard Hipp <[EMAIL PROTECTED]
#endif
void* InitializeRecursiveMutex(void)
{
//
// NULL - Security contect
// 0 - Not initial owner
// NULL - Not assigning a name to the mutex
//
HANDLE hMutex = CreateMutex(NULL,0,NULL);
return((void*)hMutex);
}
void EnterRecursiveMutex(void* pHandle)
{
//
// Wait on the mutex for an infinite period
//
WaitForSingleObject((HANDLE)pHandle,INFINITE);
}
void LeaveRecursiveMutex(void* pHandle)
{
ReleaseMutex((HANDLE)pHandle);
}
int TryEnterRecursiveMutex(void* pHandle)
{
//
// Wait on the mutex for a 0 period. We either get the lock immediately
// or fail out
//
int nRetval = WaitForSingleObject((HANDLE)pHandle,0);
if( nRetval == WAIT_TIMEOUT )
{
return(-1);
}
return(0);
}
void DestroyRecursiveMutex(void* pHandle)
{
CloseHandle((HANDLE)pHandle);
}
#endif // WIN32