Обсуждение: Re: [PATCHES] Compiling libpq with VisualC

Поиск
Список
Период
Сортировка

Re: [PATCHES] Compiling libpq with VisualC

От
"Magnus Hagander"
Дата:
> >>What is the recommended way to create mutex objects
> (CreateMutex) from
> >>Win32 libraries?  There must be a clean way like there is
> in pthreads.
> >>
> >>
> >
> >A mutex is inherently a global object. CreateMutex(NULL,
> FALSE, NULL)
> >will return a handle to an unowned mutex.
> >
> >
> >
> That's not the problem. Under pthread, it's possible to
> initialize a mutex from compile time:
>
>     static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
>
> This means that the mutex is immediately valid, no races with
> the initialization. I couldn't find an equivalent Win32 feature.

AFAIK, there is no such thing on Win32. The clean way is probably to
rqeuire the library to export a function InitialyzeFooLibrary() that
does it (like Winsock does with requiring WSAStartup()).

To do something like it though, you can use a named mutex. Then doing,
in pseudocode:

if (CreateMutex(...,"my_unique_mutex_name") == ERROR_ALREADY_EXISTS)
   OpenMutex(...,"my_unique_mutex_name")

Assuming nobody closes the mutex between your attempt to create and open
(which shouldn't happen if you just ignore closing it until process
exit), this should be safe.

Store the HANDLE to the Mutex in TLS, and have each thread do the
create/open when it needs the mutex (e.g. wrap the wait on the mutex in
a function/macro that will create/open the mutex if it's
INVALID_HANDLE_VALUE, which you assign it to by default).


You need a unique name for the mutex, since it's not per-process but
per-sessino. But that can easily be constructed from the pid.

//Magnus


Re: [pgsql-hackers-win32] [PATCHES] Compiling libpq with

От
Andreas Pflug
Дата:
Magnus Hagander wrote:

>>>>What is the recommended way to create mutex objects
>>>>
>>>>
>>(CreateMutex) from
>>
>>
>>>>Win32 libraries?  There must be a clean way like there is
>>>>
>>>>
>>in pthreads.
>>
>>
>>>>
>>>>
>>>>
>>>>
>>>A mutex is inherently a global object. CreateMutex(NULL,
>>>
>>>
>>FALSE, NULL)
>>
>>
>>>will return a handle to an unowned mutex.
>>>
>>>
>>>
>>>
>>>
>>That's not the problem. Under pthread, it's possible to
>>initialize a mutex from compile time:
>>
>>    static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
>>
>>This means that the mutex is immediately valid, no races with
>>the initialization. I couldn't find an equivalent Win32 feature.
>>
>>
>
>AFAIK, there is no such thing on Win32. The clean way is probably to
>rqeuire the library to export a function InitialyzeFooLibrary() that
>does it (like Winsock does with requiring WSAStartup()).
>
>To do something like it though, you can use a named mutex. Then doing,
>in pseudocode:
>
>if (CreateMutex(...,"my_unique_mutex_name") == ERROR_ALREADY_EXISTS)
>   OpenMutex(...,"my_unique_mutex_name")
>
>Assuming nobody closes the mutex between your attempt to create and open
>(which shouldn't happen if you just ignore closing it until process
>exit), this should be safe.
>
>Store the HANDLE to the Mutex in TLS, and have each thread do the
>create/open when it needs the mutex (e.g. wrap the wait on the mutex in
>a function/macro that will create/open the mutex if it's
>INVALID_HANDLE_VALUE, which you assign it to by default).
>
>
>You need a unique name for the mutex, since it's not per-process but
>per-sessino. But that can easily be constructed from the pid.
>
>

A libpq patch avoiding the InitializeFooLibrary() creating the mutex
on-demand is in pgsql-patches already.

+#ifndef WIN32
     static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
+#else
+    static pthread_mutex_t singlethread_lock;
+        static long mutex_initialized = 0;
+        if (!InterlockedExchange(&mutex_initialized, 1L))
+                pthread_mutex_init(&singlethread_lock, NULL); // wraps
CreateMutex(NULL,FALSE,NULL)
+#endif

Regards,
Andreas