Fixed some bugs in thread safeness for wnd struct.
diff --git a/windows/win.c b/windows/win.c
index 5cf69a4..e2ea887 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -54,7 +54,6 @@
/* thread safeness */
static CRITICAL_SECTION WIN_CritSection;
-static int ilockCounter = 0;
/***********************************************************************
* WIN_LockWnds
@@ -64,6 +63,9 @@
void WIN_LockWnds()
{
/*
+ This code will be released in the future
+ info : francois@macadamian.com
+
EnterCriticalSection(&WIN_CritSection);
*/
}
@@ -76,6 +78,9 @@
void WIN_UnlockWnds()
{
/*
+ This code will be released in the future
+ info : francois@macadamian.com
+
LeaveCriticalSection(&WIN_CritSection);
*/
}
@@ -87,12 +92,24 @@
*/
int WIN_SuspendWndsLock()
{
-/*
- int isuspendedLocks = WIN_CritSection.RecursionCount;
- WIN_CritSection.RecursionCount = 0;
- LeaveCriticalSection(&WIN_CritSection);
+ int isuspendedLocks = 0;
+
+ /* make sure that the lock is not suspended by different thread than
+ the owning thread */
+ if(WIN_CritSection.OwningThread != GetCurrentThreadId())
+ {
+ return 0;
+ }
+ /* set the value of isuspendedlock to the actual recursion count
+ of the critical section */
+ isuspendedLocks = WIN_CritSection.RecursionCount;
+ /* set the recursion count of the critical section to 1
+ so the owning thread will be able to leave it */
+ WIN_CritSection.RecursionCount = 1;
+ /* leave critical section*/
+ WIN_UnlockWnds();
+
return isuspendedLocks;
-*/
}
/***********************************************************************
@@ -100,13 +117,20 @@
*
* Restore the suspended locks on WND structures
*/
-void WIN_RestoreWndslock(int ipreviousLocks)
+void WIN_RestoreWndsLock(int ipreviousLocks)
{
-/*
- EnterCriticalSection(&WIN_CritSection);
+ if(!ipreviousLocks)
+ {
+ return;
+ }
+ /* restore the lock */
+ WIN_LockWnds();
+ /* set the recursion count of the critical section to the
+ value of suspended locks (given by WIN_SuspendWndsLock())*/
WIN_CritSection.RecursionCount = ipreviousLocks;
-*/
+
}
+
/***********************************************************************
* WIN_FindWndPtr
*
@@ -118,25 +142,25 @@
if (!hwnd || HIWORD(hwnd)) goto error2;
ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
- /* Lock all WND structures for thread safeness
- WIN_LockWnds(ptr);
- and increment destruction monitoring
+ /* Lock all WND structures for thread safeness*/
+ WIN_LockWnds();
+ /*and increment destruction monitoring*/
ptr->irefCount++;
- */
+
if (ptr->dwMagic != WND_MAGIC) goto error;
if (ptr->hwndSelf != hwnd)
{
- ERR( win, "Can't happen: hwnd %04x self pointer is %04x\n",
- hwnd, ptr->hwndSelf );
+ ERR( win, "Can't happen: hwnd %04x self pointer is %04x\n",hwnd, ptr->hwndSelf );
goto error;
}
+ /* returns a locked pointer */
return ptr;
error:
- /* Unlock all WND structures for thread safeness
- WIN_UnlockWnds(ptr);
- and decrement destruction monitoring value
+ /* Unlock all WND structures for thread safeness*/
+ WIN_UnlockWnds();
+ /* and decrement destruction monitoring value */
ptr->irefCount--;
- */
+
error2:
if ( hwnd!=0 )
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
@@ -152,12 +176,13 @@
*/
WND *WIN_LockWndPtr(WND *initWndPtr)
{
-
if(!initWndPtr) return 0;
- /*
+
+ /* Lock all WND structures for thread safeness*/
WIN_LockWnds();
+ /*and increment destruction monitoring*/
initWndPtr->irefCount++;
- */
+
return initWndPtr;
}
@@ -169,22 +194,26 @@
*/
void WIN_ReleaseWndPtr(WND *wndPtr)
{
-
if(!wndPtr) return;
- /*Decrement destruction monitoring value
+
+ /*Decrement destruction monitoring value*/
wndPtr->irefCount--;
- Check if it's time to release the memory
+ /* Check if it's time to release the memory*/
if(wndPtr->irefCount == 0)
{
- Add memory releasing code here
+ /*Add memory releasing code here*/
}
- unlock all WND structures for thread safeness
+ else if(wndPtr->irefCount < 0)
+ {
+ /* This else if is useful to monitor the WIN_ReleaseWndPtr function */
+ TRACE(win,"forgot a Lock on %p somewhere\n",wndPtr);
+ }
+ /*unlock all WND structures for thread safeness*/
WIN_UnlockWnds();
- */
}
/***********************************************************************
- * WIN_ReleaseWndPtr
+ * WIN_UpdateWndPtr
*
* Updates the value of oldPtr to newPtr.
*/
@@ -376,17 +405,21 @@
pWnd->hwndSelf );
}
else if ((pWnd->hmemTaskQ == hQueue) &&
- (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT))) break;
+ (pWnd->hrgnUpdate || (pWnd->flags & WIN_INTERNAL_PAINT)))
+ break;
else if (pWnd->child )
if ((hwndRet = WIN_FindWinToRepaint( pWnd->child->hwndSelf, hQueue )) )
- goto end;
+ {
+ WIN_ReleaseWndPtr(pWnd);
+ return hwndRet;
+ }
+
}
if(!pWnd)
{
- hwndRet = 0;
- goto end;
+ return 0;
}
hwndRet = pWnd->hwndSelf;
@@ -397,10 +430,12 @@
{
WIN_UpdateWndPtr(&pWnd,pWnd->next);
}
- if (pWnd) hwndRet = pWnd->hwndSelf;
- TRACE(win,"found %04x\n",hwndRet);
- end:
+ if (pWnd)
+ {
+ hwndRet = pWnd->hwndSelf;
WIN_ReleaseWndPtr(pWnd);
+ }
+ TRACE(win,"found %04x\n",hwndRet);
return hwndRet;
}
@@ -574,6 +609,11 @@
TRACE(win,"Creating desktop window\n");
+
+ /* Initialisation of the critical section for thread safeness */
+ InitializeCriticalSection(&WIN_CritSection);
+ MakeCriticalSectionGlobal(&WIN_CritSection);
+
if (!ICONTITLE_Init() ||
!WINPOS_CreateInternalPosAtom() ||
!(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 )))
@@ -632,11 +672,6 @@
return FALSE;
SendMessageA( hwndDesktop, WM_NCCREATE, 0, 0 );
-
- /* Initialisation of the critical section for thread safeness
- InitializeCriticalSection(&WIN_CritSection);
- MakeCriticalSectionGlobal(&WIN_CritSection);
- */
pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
return TRUE;
}
@@ -748,8 +783,10 @@
wndPtr->owner = NULL;
else
{
- wndPtr->owner = WIN_GetTopParentPtr(WIN_FindWndPtr(cs->hwndParent));
+ WND *tmpWnd = WIN_FindWndPtr(cs->hwndParent);
+ wndPtr->owner = WIN_GetTopParentPtr(tmpWnd);
WIN_ReleaseWndPtr(wndPtr->owner);
+ WIN_ReleaseWndPtr(tmpWnd);
}
}
@@ -776,6 +813,7 @@
wndPtr->userdata = 0;
wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU)
? MENU_GetSysMenu( hwnd, 0 ) : 0;
+ wndPtr->irefCount = 1;
if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
@@ -967,10 +1005,11 @@
/* Abort window creation */
WARN(win, "aborted by WM_xxCREATE!\n");
- WIN_DestroyWindow( wndPtr );
+ WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr ));
retvalue = 0;
end:
WIN_ReleaseWndPtr(wndPtr);
+
return retvalue;
}
@@ -1318,7 +1357,11 @@
}
WIN_UpdateWndPtr(&siblingPtr,siblingPtr->next);
}
- if (siblingPtr) DestroyWindow( siblingPtr->hwndSelf );
+ if (siblingPtr)
+ {
+ DestroyWindow( siblingPtr->hwndSelf );
+ WIN_ReleaseWndPtr(siblingPtr);
+ }
else break;
}
@@ -1345,7 +1388,7 @@
/* Destroy the window storage */
- WIN_DestroyWindow( wndPtr );
+ WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr ));
retvalue = TRUE;
end:
WIN_ReleaseWndPtr(wndPtr);
@@ -2312,11 +2355,13 @@
*/
WND* WIN_GetTopParentPtr( WND* pWnd )
{
- while( pWnd && (pWnd->dwStyle & WS_CHILD))
+ WND *tmpWnd = WIN_LockWndPtr(pWnd);
+
+ while( tmpWnd && (tmpWnd->dwStyle & WS_CHILD))
{
- WIN_UpdateWndPtr(&pWnd,pWnd->parent);
+ WIN_UpdateWndPtr(&tmpWnd,tmpWnd->parent);
}
- return pWnd;
+ return tmpWnd;
}
/*****************************************************************