Deadlock in SCROLL_LoadBitmaps() when another thread exits
Adam Gundy
arg at cyberscience.com
Wed Oct 15 08:10:11 CDT 2003
running WINE under valgrind causes it to deadlock in SCROLL_LoadBitmaps()
if another thread is exiting at the same time (valgrind tends to find deadlocks
because things happen much more slowly).
the problem is caused by:
1) SCROLL_GetScrollBarInfo() calling SCROLL_LoadBitmaps() while still holding
a window pointer (and hence the USER_SysLevel lock).
2) The exiting thread already holds the loader_section lock since it is modifying
loader details.
3) SCROLL_LoadBitmaps() indirectly attempts to get the loader_section lock so it can
fetch the bitmaps, but waits because the other thread already has it.
4) thread_detach() indirectly tries to get the USER_SysLevel lock so it can clean
up windows that the thread owns, but waits because the other thread already has it.
result: deadlock.
I have attached a patch which stops SCROLL_LoadBitmaps() from holding the USER_SysLevel
lock while loading the bitmaps. I have also attached the trace which shows the deadlock.
Seeya,
Adam
--
Real Programmers don't comment their code. If it was hard to write,
it should be hard to read, and even harder to modify.
These are all my own opinions.
-------------- next part --------------
Index: controls/scroll.c
===================================================================
RCS file: /home/wine/wine/controls/scroll.c,v
retrieving revision 1.70
diff -u -r1.70 scroll.c
--- controls/scroll.c 17 Sep 2003 04:28:28 -0000 1.70
+++ controls/scroll.c 15 Oct 2003 12:54:51 -0000
@@ -42,6 +42,14 @@
UINT flags; /* EnableScrollBar flags */
} SCROLLBAR_INFO, *LPSCROLLBAR_INFO;
+static CRITICAL_SECTION scroll_section;
+static CRITICAL_SECTION_DEBUG critsect_debug =
+{
+ 0, 0, &scroll_section,
+ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+ 0, 0, { 0, (DWORD)(__FILE__ ": scroll_section") }
+};
+static CRITICAL_SECTION scroll_section = { &critsect_debug, -1, 0, 0, 0, 0 };
static HBITMAP hUpArrow;
static HBITMAP hDnArrow;
@@ -159,18 +167,23 @@
*/
static void SCROLL_LoadBitmaps(void)
{
- hUpArrow = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_UPARROW) );
- hDnArrow = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_DNARROW) );
- hLfArrow = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_LFARROW) );
- hRgArrow = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RGARROW) );
- hUpArrowD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_UPARROWD) );
- hDnArrowD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_DNARROWD) );
- hLfArrowD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_LFARROWD) );
- hRgArrowD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RGARROWD) );
- hUpArrowI = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_UPARROWI) );
- hDnArrowI = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_DNARROWI) );
- hLfArrowI = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_LFARROWI) );
- hRgArrowI = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RGARROWI) );
+ EnterCriticalSection( &scroll_section );
+ if (!hUpArrow)
+ {
+ hUpArrow = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_UPARROW) );
+ hDnArrow = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_DNARROW) );
+ hLfArrow = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_LFARROW) );
+ hRgArrow = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RGARROW) );
+ hUpArrowD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_UPARROWD) );
+ hDnArrowD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_DNARROWD) );
+ hLfArrowD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_LFARROWD) );
+ hRgArrowD = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RGARROWD) );
+ hUpArrowI = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_UPARROWI) );
+ hDnArrowI = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_DNARROWI) );
+ hLfArrowI = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_LFARROWI) );
+ hRgArrowI = LoadBitmapA( 0, MAKEINTRESOURCEA(OBM_RGARROWI) );
+ }
+ LeaveCriticalSection( &scroll_section );
}
@@ -203,9 +216,13 @@
if (nBar == SB_HORZ) wndPtr->pHScroll = infoPtr;
else wndPtr->pVScroll = infoPtr;
}
- if (!hUpArrow) SCROLL_LoadBitmaps();
+ WIN_ReleaseWndPtr( wndPtr );
+ SCROLL_LoadBitmaps();
+ }
+ else
+ {
+ WIN_ReleaseWndPtr( wndPtr );
}
- WIN_ReleaseWndPtr( wndPtr );
return infoPtr;
}
@@ -1340,7 +1357,7 @@
{
case WM_CREATE:
SCROLL_CreateScrollBar(hwnd, (LPCREATESTRUCTW)lParam);
- if (!hUpArrow) SCROLL_LoadBitmaps();
+ SCROLL_LoadBitmaps();
break;
case WM_ENABLE:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: tt
Type: application/octet-stream
Size: 4568 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-patches/attachments/20031015/f01e985b/tt.obj
More information about the wine-patches
mailing list