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


Reply via email to