Make VIRTUAL_SetFaultHandler an internal function
Dimitrie O. Paun
dpaun at rogers.com
Mon Apr 18 07:18:58 CDT 2005
On Mon, Apr 18, 2005 at 01:06:23PM +0200, Alexandre Julliard wrote:
> Sure, the general idea is fine. You actually don't need a mem_area
> structure at all, you can store that directly in the phys bitmap. Also
> it would be nice to only set the handler when a DIB is allocated, not
> at startup.
Right, I realized that after sending the email about making the data
field a pointer to physBitmap. Compiles, but not tested, as I don't
have a DIB using app.
ChangeLog
Remove the VIRTUAL_SetFaultHandler(), use vectored exceptions instead.
Index: dlls/ntdll/ntdll.spec
===================================================================
RCS file: /var/cvs/wine/dlls/ntdll/ntdll.spec,v
retrieving revision 1.177
diff -u -p -r1.177 ntdll.spec
--- dlls/ntdll/ntdll.spec 16 Apr 2005 11:19:27 -0000 1.177
+++ dlls/ntdll/ntdll.spec 18 Apr 2005 11:42:07 -0000
@@ -1036,4 +1036,3 @@
@ cdecl MODULE_DllThreadAttach(ptr)
@ cdecl MODULE_GetLoadOrderW(ptr wstr wstr)
@ cdecl VERSION_Init(wstr)
-@ cdecl VIRTUAL_SetFaultHandler(ptr ptr ptr)
Index: dlls/ntdll/virtual.c
===================================================================
RCS file: /var/cvs/wine/dlls/ntdll/virtual.c,v
retrieving revision 1.46
diff -u -p -r1.46 virtual.c
--- dlls/ntdll/virtual.c 22 Feb 2005 19:33:50 -0000 1.46
+++ dlls/ntdll/virtual.c 17 Apr 2005 04:20:14 -0000
@@ -1098,25 +1104,6 @@ void virtual_init(void)
/***********************************************************************
- * VIRTUAL_SetFaultHandler
- */
-BOOL VIRTUAL_SetFaultHandler( LPCVOID addr, HANDLERPROC proc, LPVOID arg )
-{
- FILE_VIEW *view;
- BOOL ret = FALSE;
-
- RtlEnterCriticalSection( &csVirtual );
- if ((view = VIRTUAL_FindView( addr )))
- {
- view->handlerProc = proc;
- view->handlerArg = arg;
- ret = TRUE;
- }
- RtlLeaveCriticalSection( &csVirtual );
- return ret;
-}
-
-/***********************************************************************
* VIRTUAL_HandleFault
*/
DWORD VIRTUAL_HandleFault( LPCVOID addr )
Index: dlls/x11drv/dib.c
===================================================================
RCS file: /var/cvs/wine/dlls/x11drv/dib.c,v
retrieving revision 1.35
diff -u -p -r1.35 dib.c
--- dlls/x11drv/dib.c 14 Apr 2005 12:48:31 -0000 1.35
+++ dlls/x11drv/dib.c 18 Apr 2005 12:14:34 -0000
@@ -38,11 +38,25 @@
#include "winbase.h"
#include "wingdi.h"
#include "x11drv.h"
+#include "excpt.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
WINE_DECLARE_DEBUG_CHANNEL(x11drv);
+static struct list dibs_list = LIST_INIT(dibs_list);
+
+static CRITICAL_SECTION dibs_cs;
+static CRITICAL_SECTION_DEBUG dibs_cs_debug =
+{
+ 0, 0, &dibs_cs,
+ { &dibs_cs_debug.ProcessLocksList, &dibs_cs_debug.ProcessLocksList },
+ 0, 0, { 0, (DWORD)(__FILE__ ": dibs_cs") }
+};
+static CRITICAL_SECTION dibs_cs = { &dibs_cs_debug, -1, 0, 0, 0, 0 };
+
+PVOID dibs_handler = 0;
+
static int ximageDepthTable[32];
/* This structure holds the arguments for DIB_SetImageBits() */
@@ -4268,22 +4282,43 @@ static void X11DRV_DIB_DoUpdateDIBSectio
/***********************************************************************
* X11DRV_DIB_FaultHandler
*/
-static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
+static LONG CALLBACK X11DRV_DIB_FaultHandler( PEXCEPTION_POINTERS ep )
{
- X_PHYSBITMAP *physBitmap = res;
- INT state = X11DRV_DIB_Lock( physBitmap, DIB_Status_None, FALSE );
+ X_PHYSBITMAP *physBitmap = NULL;
+ BOOL found = FALSE;
+ struct list *ptr;
+ INT state;
+
+ if (ep->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION)
+ return EXCEPTION_CONTINUE_SEARCH;
+
+ EnterCriticalSection(&dibs_cs);
+ LIST_FOR_EACH( ptr, &dibs_list )
+ {
+ physBitmap = LIST_ENTRY( ptr, X_PHYSBITMAP, entry );
+ if (physBitmap->base > ep->ExceptionRecord->ExceptionAddress) break;
+ if ((const char*)ep->ExceptionRecord->ExceptionAddress <
+ (const char*)physBitmap->base + physBitmap->size)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ LeaveCriticalSection(&dibs_cs);
- if (state != DIB_Status_InSync) {
- /* no way to tell whether app needs read or write yet,
- * try read first */
- X11DRV_DIB_Coerce( physBitmap, DIB_Status_InSync, FALSE );
- } else {
- /* hm, apparently the app must have write access */
- X11DRV_DIB_Coerce( physBitmap, DIB_Status_AppMod, FALSE );
- }
- X11DRV_DIB_Unlock( physBitmap, TRUE );
+ if (!found) return EXCEPTION_CONTINUE_SEARCH;
- return TRUE;
+ state = X11DRV_DIB_Lock( physBitmap, DIB_Status_None, FALSE );
+ if (state != DIB_Status_InSync) {
+ /* no way to tell whether app needs read or write yet, try read first */
+ X11DRV_DIB_Coerce( physBitmap, DIB_Status_InSync, FALSE );
+ } else {
+ /* hm, apparently the app must have write access */
+ X11DRV_DIB_Coerce( physBitmap, DIB_Status_AppMod, FALSE );
+ }
+ X11DRV_DIB_Unlock( physBitmap, TRUE );
+
+ return EXCEPTION_CONTINUE_EXECUTION;
}
/***********************************************************************
@@ -4566,7 +4601,6 @@ static XImage *X11DRV_XShmCreateImage( i
HBITMAP X11DRV_CreateDIBSection( X11DRV_PDEVICE *physDev, HBITMAP hbitmap,
const BITMAPINFO *bmi, UINT usage )
{
- extern BOOL VIRTUAL_SetFaultHandler(LPCVOID addr, BOOL (*proc)(LPVOID, LPCVOID), LPVOID arg);
X_PHYSBITMAP *physBitmap;
DIBSECTION dib;
@@ -4602,11 +4636,18 @@ HBITMAP X11DRV_CreateDIBSection( X11DRV_
/* install fault handler */
InitializeCriticalSection( &physBitmap->lock );
- if (VIRTUAL_SetFaultHandler(dib.dsBm.bmBits, X11DRV_DIB_FaultHandler, physBitmap))
- {
- X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_READWRITE );
- physBitmap->status = DIB_Status_AppMod;
- }
+
+ physBitmap->base = dib.dsBm.bmBits;
+ physBitmap->size = dib.dsBmih.biSize;
+ physBitmap->status = DIB_Status_AppMod;
+
+ EnterCriticalSection( &dibs_cs );
+ list_add_head( &dibs_list, &physBitmap->entry );
+ if (!dibs_handler)
+ dibs_handler = AddVectoredExceptionHandler( TRUE, X11DRV_DIB_FaultHandler );
+ LeaveCriticalSection( &dibs_cs );
+
+ X11DRV_DIB_DoProtectDIBSection( physBitmap, PAGE_READWRITE );
return hbitmap;
}
@@ -4616,6 +4657,10 @@ HBITMAP X11DRV_CreateDIBSection( X11DRV_
*/
void X11DRV_DIB_DeleteDIBSection(X_PHYSBITMAP *physBitmap, DIBSECTION *dib)
{
+ EnterCriticalSection( &dibs_cs );
+ list_remove( &physBitmap->entry );
+ LeaveCriticalSection( &dibs_cs );
+
if (dib->dshSection)
X11DRV_DIB_Coerce(physBitmap, DIB_Status_InSync, FALSE);
Index: dlls/x11drv/x11drv.h
===================================================================
RCS file: /var/cvs/wine/dlls/x11drv/x11drv.h,v
retrieving revision 1.69
diff -u -p -r1.69 x11drv.h
--- dlls/x11drv/x11drv.h 14 Apr 2005 12:48:11 -0000 1.69
+++ dlls/x11drv/x11drv.h 18 Apr 2005 12:13:43 -0000
@@ -64,6 +64,7 @@ typedef int Status;
#include "winuser.h"
#include "ddrawi.h"
#include "thread.h"
+#include "wine/list.h"
#define MAX_PIXELFORMATS 8
@@ -111,6 +112,9 @@ typedef struct
#ifdef HAVE_LIBXXSHM
XShmSegmentInfo shminfo; /* shared memory segment info */
#endif
+ struct list entry; /* Entry in global DIB list */
+ const void *base; /* Base address */
+ SIZE_T size; /* Size in bytes */
} X_PHYSBITMAP;
/* X physical font */
@@ -147,6 +151,7 @@ typedef struct
/* GCs used for B&W and color bitmap operations */
extern GC BITMAP_monoGC, BITMAP_colorGC;
extern X_PHYSBITMAP BITMAP_stock_phys_bitmap; /* phys bitmap for the default stock bitmap */
+extern PVOID dibs_handler;
#define BITMAP_GC(physBitmap) (((physBitmap)->pixmap_depth == 1) ? BITMAP_monoGC : BITMAP_colorGC)
Index: dlls/x11drv/x11drv_main.c
===================================================================
RCS file: /var/cvs/wine/dlls/x11drv/x11drv_main.c,v
retrieving revision 1.102
diff -u -p -r1.102 x11drv_main.c
--- dlls/x11drv/x11drv_main.c 14 Apr 2005 12:48:11 -0000 1.102
+++ dlls/x11drv/x11drv_main.c 18 Apr 2005 12:06:15 -0000
@@ -422,6 +422,9 @@ static void process_detach(void)
/* cleanup GDI */
X11DRV_GDI_Finalize();
+ /* cleanup DIB handling */
+ if (dibs_handler) RemoveVectoredExceptionHandler( dibs_handler );
+
DeleteCriticalSection( &X11DRV_CritSection );
}
--
Dimi.
More information about the wine-devel
mailing list