Commit 9aa1cd06 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

gdi32: Use pthread mutex instead of gdi_section.

parent 2e140446
...@@ -518,8 +518,6 @@ static BOOL DC_DeleteObject( HGDIOBJ handle ) ...@@ -518,8 +518,6 @@ static BOOL DC_DeleteObject( HGDIOBJ handle )
TRACE( "%p\n", handle ); TRACE( "%p\n", handle );
GDI_CheckNotLock();
if (!(dc = get_dc_ptr( handle ))) return FALSE; if (!(dc = get_dc_ptr( handle ))) return FALSE;
if (dc->refcount != 1) if (dc->refcount != 1)
{ {
...@@ -528,7 +526,8 @@ static BOOL DC_DeleteObject( HGDIOBJ handle ) ...@@ -528,7 +526,8 @@ static BOOL DC_DeleteObject( HGDIOBJ handle )
return FALSE; return FALSE;
} }
/* Call hook procedure to check whether is it OK to delete this DC */ /* Call hook procedure to check whether is it OK to delete this DC,
* gdi_lock should not be locked */
if (dc->hookProc && !dc->hookProc( dc->hSelf, DCHC_DELETEDC, dc->dwHookData, 0 )) if (dc->hookProc && !dc->hookProc( dc->hSelf, DCHC_DELETEDC, dc->dwHookData, 0 ))
{ {
release_dc_ptr( dc ); release_dc_ptr( dc );
...@@ -726,8 +725,7 @@ HDC WINAPI NtGdiOpenDCW( UNICODE_STRING *device, const DEVMODEW *devmode, UNICOD ...@@ -726,8 +725,7 @@ HDC WINAPI NtGdiOpenDCW( UNICODE_STRING *device, const DEVMODEW *devmode, UNICOD
HDC hdc; HDC hdc;
DC * dc; DC * dc;
GDI_CheckNotLock(); /* gdi_lock should not be locked */
if (is_display) if (is_display)
funcs = get_display_driver(); funcs = get_display_driver();
else if (hspool) else if (hspool)
...@@ -788,7 +786,7 @@ HDC WINAPI NtGdiCreateCompatibleDC( HDC hdc ) ...@@ -788,7 +786,7 @@ HDC WINAPI NtGdiCreateCompatibleDC( HDC hdc )
const struct gdi_dc_funcs *funcs; const struct gdi_dc_funcs *funcs;
PHYSDEV physDev = NULL; PHYSDEV physDev = NULL;
GDI_CheckNotLock(); /* gdi_lock should not be locked */
if (hdc) if (hdc)
{ {
......
...@@ -747,7 +747,7 @@ static inline struct windrv_physdev *get_windrv_physdev( PHYSDEV dev ) ...@@ -747,7 +747,7 @@ static inline struct windrv_physdev *get_windrv_physdev( PHYSDEV dev )
static inline void lock_surface( struct windrv_physdev *dev ) static inline void lock_surface( struct windrv_physdev *dev )
{ {
GDI_CheckNotLock(); /* gdi_lock should not be locked */
dev->surface->funcs->lock( dev->surface ); dev->surface->funcs->lock( dev->surface );
if (is_rect_empty( dev->dibdrv->bounds )) dev->start_ticks = NtGetTickCount(); if (is_rect_empty( dev->dibdrv->bounds )) dev->start_ticks = NtGetTickCount();
} }
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <pthread.h>
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
...@@ -88,14 +89,7 @@ static const LOGBRUSH DkGrayBrush = { BS_SOLID, RGB(64,64,64), 0 }; ...@@ -88,14 +89,7 @@ static const LOGBRUSH DkGrayBrush = { BS_SOLID, RGB(64,64,64), 0 };
static const LOGBRUSH DCBrush = { BS_SOLID, RGB(255,255,255), 0 }; static const LOGBRUSH DCBrush = { BS_SOLID, RGB(255,255,255), 0 };
static CRITICAL_SECTION gdi_section; static pthread_mutex_t gdi_lock;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
0, 0, &gdi_section,
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": gdi_section") }
};
static CRITICAL_SECTION gdi_section = { &critsect_debug, -1, 0, 0, 0, 0 };
/**************************************************************************** /****************************************************************************
...@@ -469,9 +463,9 @@ void CDECL __wine_make_gdi_object_system( HGDIOBJ handle, BOOL set) ...@@ -469,9 +463,9 @@ void CDECL __wine_make_gdi_object_system( HGDIOBJ handle, BOOL set)
{ {
GDI_HANDLE_ENTRY *entry; GDI_HANDLE_ENTRY *entry;
EnterCriticalSection( &gdi_section ); pthread_mutex_lock( &gdi_lock );
if ((entry = handle_entry( handle ))) entry_obj( entry )->system = !!set; if ((entry = handle_entry( handle ))) entry_obj( entry )->system = !!set;
LeaveCriticalSection( &gdi_section ); pthread_mutex_unlock( &gdi_lock );
} }
/****************************************************************************** /******************************************************************************
...@@ -525,9 +519,9 @@ UINT GDI_get_ref_count( HGDIOBJ handle ) ...@@ -525,9 +519,9 @@ UINT GDI_get_ref_count( HGDIOBJ handle )
GDI_HANDLE_ENTRY *entry; GDI_HANDLE_ENTRY *entry;
UINT ret = 0; UINT ret = 0;
EnterCriticalSection( &gdi_section ); pthread_mutex_lock( &gdi_lock );
if ((entry = handle_entry( handle ))) ret = entry_obj( entry )->selcount; if ((entry = handle_entry( handle ))) ret = entry_obj( entry )->selcount;
LeaveCriticalSection( &gdi_section ); pthread_mutex_unlock( &gdi_lock );
return ret; return ret;
} }
...@@ -541,10 +535,10 @@ HGDIOBJ GDI_inc_ref_count( HGDIOBJ handle ) ...@@ -541,10 +535,10 @@ HGDIOBJ GDI_inc_ref_count( HGDIOBJ handle )
{ {
GDI_HANDLE_ENTRY *entry; GDI_HANDLE_ENTRY *entry;
EnterCriticalSection( &gdi_section ); pthread_mutex_lock( &gdi_lock );
if ((entry = handle_entry( handle ))) entry_obj( entry )->selcount++; if ((entry = handle_entry( handle ))) entry_obj( entry )->selcount++;
else handle = 0; else handle = 0;
LeaveCriticalSection( &gdi_section ); pthread_mutex_unlock( &gdi_lock );
return handle; return handle;
} }
...@@ -558,7 +552,7 @@ BOOL GDI_dec_ref_count( HGDIOBJ handle ) ...@@ -558,7 +552,7 @@ BOOL GDI_dec_ref_count( HGDIOBJ handle )
{ {
GDI_HANDLE_ENTRY *entry; GDI_HANDLE_ENTRY *entry;
EnterCriticalSection( &gdi_section ); pthread_mutex_lock( &gdi_lock );
if ((entry = handle_entry( handle ))) if ((entry = handle_entry( handle )))
{ {
assert( entry_obj( entry )->selcount ); assert( entry_obj( entry )->selcount );
...@@ -566,13 +560,13 @@ BOOL GDI_dec_ref_count( HGDIOBJ handle ) ...@@ -566,13 +560,13 @@ BOOL GDI_dec_ref_count( HGDIOBJ handle )
{ {
/* handle delayed DeleteObject*/ /* handle delayed DeleteObject*/
entry_obj( entry )->deleted = 0; entry_obj( entry )->deleted = 0;
LeaveCriticalSection( &gdi_section ); pthread_mutex_unlock( &gdi_lock );
TRACE( "executing delayed DeleteObject for %p\n", handle ); TRACE( "executing delayed DeleteObject for %p\n", handle );
NtGdiDeleteObjectApp( handle ); NtGdiDeleteObjectApp( handle );
return TRUE; return TRUE;
} }
} }
LeaveCriticalSection( &gdi_section ); pthread_mutex_unlock( &gdi_lock );
return entry != NULL; return entry != NULL;
} }
...@@ -736,7 +730,7 @@ static void dump_gdi_objects( void ) ...@@ -736,7 +730,7 @@ static void dump_gdi_objects( void )
TRACE( "%u objects:\n", GDI_MAX_HANDLE_COUNT ); TRACE( "%u objects:\n", GDI_MAX_HANDLE_COUNT );
EnterCriticalSection( &gdi_section ); pthread_mutex_lock( &gdi_lock );
for (entry = gdi_shared->Handles; entry < next_unused; entry++) for (entry = gdi_shared->Handles; entry < next_unused; entry++)
{ {
if (!entry->Type) if (!entry->Type)
...@@ -747,7 +741,7 @@ static void dump_gdi_objects( void ) ...@@ -747,7 +741,7 @@ static void dump_gdi_objects( void )
gdi_obj_type( entry->ExtType << NTGDI_HANDLE_TYPE_SHIFT ), gdi_obj_type( entry->ExtType << NTGDI_HANDLE_TYPE_SHIFT ),
entry_obj( entry )->selcount, entry_obj( entry )->deleted ); entry_obj( entry )->selcount, entry_obj( entry )->deleted );
} }
LeaveCriticalSection( &gdi_section ); pthread_mutex_unlock( &gdi_lock );
} }
/*********************************************************************** /***********************************************************************
...@@ -762,7 +756,7 @@ HGDIOBJ alloc_gdi_handle( struct gdi_obj_header *obj, DWORD type, const struct g ...@@ -762,7 +756,7 @@ HGDIOBJ alloc_gdi_handle( struct gdi_obj_header *obj, DWORD type, const struct g
assert( type ); /* type 0 is reserved to mark free entries */ assert( type ); /* type 0 is reserved to mark free entries */
EnterCriticalSection( &gdi_section ); pthread_mutex_lock( &gdi_lock );
entry = next_free; entry = next_free;
if (entry) if (entry)
...@@ -771,7 +765,7 @@ HGDIOBJ alloc_gdi_handle( struct gdi_obj_header *obj, DWORD type, const struct g ...@@ -771,7 +765,7 @@ HGDIOBJ alloc_gdi_handle( struct gdi_obj_header *obj, DWORD type, const struct g
entry = next_unused++; entry = next_unused++;
else else
{ {
LeaveCriticalSection( &gdi_section ); pthread_mutex_unlock( &gdi_lock );
ERR( "out of GDI object handles, expect a crash\n" ); ERR( "out of GDI object handles, expect a crash\n" );
if (TRACE_ON(gdi)) dump_gdi_objects(); if (TRACE_ON(gdi)) dump_gdi_objects();
return 0; return 0;
...@@ -785,7 +779,7 @@ HGDIOBJ alloc_gdi_handle( struct gdi_obj_header *obj, DWORD type, const struct g ...@@ -785,7 +779,7 @@ HGDIOBJ alloc_gdi_handle( struct gdi_obj_header *obj, DWORD type, const struct g
entry->Type = entry->ExtType & 0x1f; entry->Type = entry->ExtType & 0x1f;
if (++entry->Generation == 0xff) entry->Generation = 1; if (++entry->Generation == 0xff) entry->Generation = 1;
ret = entry_to_handle( entry ); ret = entry_to_handle( entry );
LeaveCriticalSection( &gdi_section ); pthread_mutex_unlock( &gdi_lock );
TRACE( "allocated %s %p %u/%u\n", gdi_obj_type(type), ret, TRACE( "allocated %s %p %u/%u\n", gdi_obj_type(type), ret,
InterlockedIncrement( &debug_count ), GDI_MAX_HANDLE_COUNT ); InterlockedIncrement( &debug_count ), GDI_MAX_HANDLE_COUNT );
return ret; return ret;
...@@ -802,7 +796,7 @@ void *free_gdi_handle( HGDIOBJ handle ) ...@@ -802,7 +796,7 @@ void *free_gdi_handle( HGDIOBJ handle )
void *object = NULL; void *object = NULL;
GDI_HANDLE_ENTRY *entry; GDI_HANDLE_ENTRY *entry;
EnterCriticalSection( &gdi_section ); pthread_mutex_lock( &gdi_lock );
if ((entry = handle_entry( handle ))) if ((entry = handle_entry( handle )))
{ {
TRACE( "freed %s %p %u/%u\n", gdi_obj_type( entry->ExtType << NTGDI_HANDLE_TYPE_SHIFT ), TRACE( "freed %s %p %u/%u\n", gdi_obj_type( entry->ExtType << NTGDI_HANDLE_TYPE_SHIFT ),
...@@ -812,7 +806,7 @@ void *free_gdi_handle( HGDIOBJ handle ) ...@@ -812,7 +806,7 @@ void *free_gdi_handle( HGDIOBJ handle )
entry->Object = (UINT_PTR)next_free; entry->Object = (UINT_PTR)next_free;
next_free = entry; next_free = entry;
} }
LeaveCriticalSection( &gdi_section ); pthread_mutex_unlock( &gdi_lock );
return object; return object;
} }
...@@ -840,7 +834,7 @@ void *get_any_obj_ptr( HGDIOBJ handle, DWORD *type ) ...@@ -840,7 +834,7 @@ void *get_any_obj_ptr( HGDIOBJ handle, DWORD *type )
void *ptr = NULL; void *ptr = NULL;
GDI_HANDLE_ENTRY *entry; GDI_HANDLE_ENTRY *entry;
EnterCriticalSection( &gdi_section ); pthread_mutex_lock( &gdi_lock );
if ((entry = handle_entry( handle ))) if ((entry = handle_entry( handle )))
{ {
...@@ -848,7 +842,7 @@ void *get_any_obj_ptr( HGDIOBJ handle, DWORD *type ) ...@@ -848,7 +842,7 @@ void *get_any_obj_ptr( HGDIOBJ handle, DWORD *type )
*type = entry->ExtType << NTGDI_HANDLE_TYPE_SHIFT; *type = entry->ExtType << NTGDI_HANDLE_TYPE_SHIFT;
} }
if (!ptr) LeaveCriticalSection( &gdi_section ); if (!ptr) pthread_mutex_unlock( &gdi_lock );
return ptr; return ptr;
} }
...@@ -877,20 +871,7 @@ void *GDI_GetObjPtr( HGDIOBJ handle, DWORD type ) ...@@ -877,20 +871,7 @@ void *GDI_GetObjPtr( HGDIOBJ handle, DWORD type )
*/ */
void GDI_ReleaseObj( HGDIOBJ handle ) void GDI_ReleaseObj( HGDIOBJ handle )
{ {
LeaveCriticalSection( &gdi_section ); pthread_mutex_unlock( &gdi_lock );
}
/***********************************************************************
* GDI_CheckNotLock
*/
void GDI_CheckNotLock(void)
{
if (RtlIsCriticalSectionLockedByThread(&gdi_section))
{
ERR( "BUG: holding GDI lock\n" );
assert( 0 );
}
} }
...@@ -914,10 +895,10 @@ BOOL WINAPI NtGdiDeleteObjectApp( HGDIOBJ obj ) ...@@ -914,10 +895,10 @@ BOOL WINAPI NtGdiDeleteObjectApp( HGDIOBJ obj )
const struct gdi_obj_funcs *funcs = NULL; const struct gdi_obj_funcs *funcs = NULL;
struct gdi_obj_header *header; struct gdi_obj_header *header;
EnterCriticalSection( &gdi_section ); pthread_mutex_lock( &gdi_lock );
if (!(entry = handle_entry( obj ))) if (!(entry = handle_entry( obj )))
{ {
LeaveCriticalSection( &gdi_section ); pthread_mutex_unlock( &gdi_lock );
return FALSE; return FALSE;
} }
...@@ -925,7 +906,7 @@ BOOL WINAPI NtGdiDeleteObjectApp( HGDIOBJ obj ) ...@@ -925,7 +906,7 @@ BOOL WINAPI NtGdiDeleteObjectApp( HGDIOBJ obj )
if (header->system) if (header->system)
{ {
TRACE("Preserving system object %p\n", obj); TRACE("Preserving system object %p\n", obj);
LeaveCriticalSection( &gdi_section ); pthread_mutex_unlock( &gdi_lock );
return TRUE; return TRUE;
} }
...@@ -938,7 +919,7 @@ BOOL WINAPI NtGdiDeleteObjectApp( HGDIOBJ obj ) ...@@ -938,7 +919,7 @@ BOOL WINAPI NtGdiDeleteObjectApp( HGDIOBJ obj )
} }
else funcs = header->funcs; else funcs = header->funcs;
LeaveCriticalSection( &gdi_section ); pthread_mutex_unlock( &gdi_lock );
TRACE("%p\n", obj ); TRACE("%p\n", obj );
...@@ -985,13 +966,13 @@ INT WINAPI NtGdiExtGetObjectW( HGDIOBJ handle, INT count, void *buffer ) ...@@ -985,13 +966,13 @@ INT WINAPI NtGdiExtGetObjectW( HGDIOBJ handle, INT count, void *buffer )
TRACE("%p %d %p\n", handle, count, buffer ); TRACE("%p %d %p\n", handle, count, buffer );
EnterCriticalSection( &gdi_section ); pthread_mutex_lock( &gdi_lock );
if ((entry = handle_entry( handle ))) if ((entry = handle_entry( handle )))
{ {
funcs = entry_obj( entry )->funcs; funcs = entry_obj( entry )->funcs;
handle = entry_to_handle( entry ); /* make it a full handle */ handle = entry_to_handle( entry ); /* make it a full handle */
} }
LeaveCriticalSection( &gdi_section ); pthread_mutex_unlock( &gdi_lock );
if (funcs && funcs->pGetObjectW) if (funcs && funcs->pGetObjectW)
{ {
...@@ -1040,13 +1021,13 @@ BOOL WINAPI NtGdiUnrealizeObject( HGDIOBJ obj ) ...@@ -1040,13 +1021,13 @@ BOOL WINAPI NtGdiUnrealizeObject( HGDIOBJ obj )
const struct gdi_obj_funcs *funcs = NULL; const struct gdi_obj_funcs *funcs = NULL;
GDI_HANDLE_ENTRY *entry; GDI_HANDLE_ENTRY *entry;
EnterCriticalSection( &gdi_section ); pthread_mutex_lock( &gdi_lock );
if ((entry = handle_entry( obj ))) if ((entry = handle_entry( obj )))
{ {
funcs = entry_obj( entry )->funcs; funcs = entry_obj( entry )->funcs;
obj = entry_to_handle( entry ); /* make it a full handle */ obj = entry_to_handle( entry ); /* make it a full handle */
} }
LeaveCriticalSection( &gdi_section ); pthread_mutex_unlock( &gdi_lock );
if (funcs && funcs->pUnrealizeObject) return funcs->pUnrealizeObject( obj ); if (funcs && funcs->pUnrealizeObject) return funcs->pUnrealizeObject( obj );
return funcs != NULL; return funcs != NULL;
...@@ -1271,10 +1252,16 @@ static struct unix_funcs unix_funcs = ...@@ -1271,10 +1252,16 @@ static struct unix_funcs unix_funcs =
NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out ) NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
{ {
pthread_mutexattr_t attr;
unsigned int dpi; unsigned int dpi;
if (reason != DLL_PROCESS_ATTACH) return 0; if (reason != DLL_PROCESS_ATTACH) return 0;
pthread_mutexattr_init( &attr );
pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );
pthread_mutex_init( &gdi_lock, &attr );
pthread_mutexattr_destroy( &attr );
NtQuerySystemInformation( SystemBasicInformation, &system_info, sizeof(system_info), NULL ); NtQuerySystemInformation( SystemBasicInformation, &system_info, sizeof(system_info), NULL );
init_gdi_shared(); init_gdi_shared();
if (!gdi_shared) return STATUS_NO_MEMORY; if (!gdi_shared) return STATUS_NO_MEMORY;
......
...@@ -373,7 +373,6 @@ extern void *free_gdi_handle( HGDIOBJ handle ) DECLSPEC_HIDDEN; ...@@ -373,7 +373,6 @@ extern void *free_gdi_handle( HGDIOBJ handle ) DECLSPEC_HIDDEN;
extern void *GDI_GetObjPtr( HGDIOBJ, DWORD ) DECLSPEC_HIDDEN; extern void *GDI_GetObjPtr( HGDIOBJ, DWORD ) DECLSPEC_HIDDEN;
extern void *get_any_obj_ptr( HGDIOBJ, DWORD * ) DECLSPEC_HIDDEN; extern void *get_any_obj_ptr( HGDIOBJ, DWORD * ) DECLSPEC_HIDDEN;
extern void GDI_ReleaseObj( HGDIOBJ ) DECLSPEC_HIDDEN; extern void GDI_ReleaseObj( HGDIOBJ ) DECLSPEC_HIDDEN;
extern void GDI_CheckNotLock(void) DECLSPEC_HIDDEN;
extern UINT GDI_get_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN; extern UINT GDI_get_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN;
extern HGDIOBJ GDI_inc_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN; extern HGDIOBJ GDI_inc_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN;
extern BOOL GDI_dec_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN; extern BOOL GDI_dec_ref_count( HGDIOBJ handle ) DECLSPEC_HIDDEN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment