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-patches mailing list