8132664: closed/javax/swing/DataTransfer/DefaultNoDrop/DefaultNoDrop.java locks on Windows
authorssadetsky
Fri, 30 Sep 2016 22:10:44 +0300
changeset 41408 9bc553d242eb
parent 41407 ac6be88670ea
child 41409 04b42eb73ee6
8132664: closed/javax/swing/DataTransfer/DefaultNoDrop/DefaultNoDrop.java locks on Windows Reviewed-by: serb
jdk/src/java.desktop/windows/native/libawt/windows/awt_DnDDS.cpp
jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp
jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_DnDDS.cpp	Fri Sep 30 22:57:41 2016 +0400
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_DnDDS.cpp	Fri Sep 30 22:10:44 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -266,11 +266,14 @@
 
     dragSource->Signal();
 
+    AwtToolkit &toolkit = AwtToolkit::GetInstance();
+    toolkit.isInDoDragDropLoop = TRUE;
     res = ::DoDragDrop(dragSource,
                        dragSource,
                        convertActionsToDROPEFFECT(dragSource->m_actions),
                        &effects
           );
+    toolkit.isInDoDragDropLoop = FALSE;
 
     if (effects == DROPEFFECT_NONE && dragSource->m_dwPerformedDropEffect != DROPEFFECT_NONE) {
         effects = dragSource->m_dwPerformedDropEffect;
@@ -626,6 +629,7 @@
  */
 
 HRESULT __stdcall  AwtDragSource::QueryContinueDrag(BOOL fEscapeKeyPressed, DWORD grfKeyState) {
+    AwtToolkit::GetInstance().eventNumber++;
     TRY;
 
     JNIEnv* env       = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
@@ -681,6 +685,7 @@
  */
 
 HRESULT __stdcall  AwtDragSource::GiveFeedback(DWORD dwEffect) {
+    AwtToolkit::GetInstance().eventNumber++;
     TRY;
 
     JNIEnv* env       = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
@@ -760,6 +765,7 @@
 
 HRESULT __stdcall AwtDragSource::GetData(FORMATETC __RPC_FAR *pFormatEtc,
                                          STGMEDIUM __RPC_FAR *pmedium) {
+    AwtToolkit::GetInstance().eventNumber++;
     TRY;
     STGMEDIUM *pPicMedia = PictureDragHelper::FindData(*pFormatEtc);
     if (NULL != pPicMedia) {
@@ -934,6 +940,7 @@
 
 HRESULT __stdcall AwtDragSource::GetDataHere(FORMATETC __RPC_FAR *pFormatEtc,
                                              STGMEDIUM __RPC_FAR *pmedium) {
+    AwtToolkit::GetInstance().eventNumber++;
     TRY;
 
     if (pmedium->pUnkForRelease != (IUnknown *)NULL) {
@@ -1036,6 +1043,7 @@
  */
 
 HRESULT __stdcall  AwtDragSource::QueryGetData(FORMATETC __RPC_FAR *pFormatEtc) {
+    AwtToolkit::GetInstance().eventNumber++;
     TRY;
 
     return MatchFormatEtc(pFormatEtc, (FORMATETC *)NULL);
@@ -1049,6 +1057,7 @@
  */
 
 HRESULT __stdcall  AwtDragSource::GetCanonicalFormatEtc(FORMATETC __RPC_FAR *pFormatEtcIn, FORMATETC __RPC_FAR *pFormatEtcOut) {
+    AwtToolkit::GetInstance().eventNumber++;
     TRY;
 
     HRESULT   res = MatchFormatEtc(pFormatEtcIn, (FORMATETC *)NULL);
@@ -1069,6 +1078,7 @@
  */
 
 HRESULT __stdcall AwtDragSource::SetData(FORMATETC __RPC_FAR *pFormatEtc, STGMEDIUM __RPC_FAR *pmedium, BOOL fRelease) {
+    AwtToolkit::GetInstance().eventNumber++;
     if (pFormatEtc->cfFormat == CF_PERFORMEDDROPEFFECT && pmedium->tymed == TYMED_HGLOBAL) {
         m_dwPerformedDropEffect = *(DWORD*)::GlobalLock(pmedium->hGlobal);
         ::GlobalUnlock(pmedium->hGlobal);
@@ -1091,6 +1101,7 @@
  */
 
 HRESULT __stdcall  AwtDragSource::EnumFormatEtc(DWORD dwDirection, IEnumFORMATETC *__RPC_FAR *ppenumFormatEtc) {
+    AwtToolkit::GetInstance().eventNumber++;
     TRY;
 
     *ppenumFormatEtc = new ADSIEnumFormatEtc(this);
@@ -1104,6 +1115,7 @@
  */
 
 HRESULT __stdcall  AwtDragSource::DAdvise(FORMATETC __RPC_FAR *pFormatEtc, DWORD advf, IAdviseSink __RPC_FAR *pAdvSink, DWORD __RPC_FAR *pdwConnection) {
+    AwtToolkit::GetInstance().eventNumber++;
     return E_NOTIMPL;
 }
 
@@ -1112,6 +1124,7 @@
  */
 
 HRESULT __stdcall  AwtDragSource::DUnadvise(DWORD dwConnection) {
+    AwtToolkit::GetInstance().eventNumber++;
     return OLE_E_ADVISENOTSUPPORTED;
 }
 
@@ -1120,6 +1133,7 @@
  */
 
 HRESULT __stdcall  AwtDragSource::EnumDAdvise(IEnumSTATDATA __RPC_FAR *__RPC_FAR *ppenumAdvise) {
+    AwtToolkit::GetInstance().eventNumber++;
     return OLE_E_ADVISENOTSUPPORTED;
 }
 
@@ -1127,7 +1141,7 @@
     ::RegisterClipboardFormat(TEXT("_SUNW_JAVA_AWT_PROCESS_ID"));
 
 HRESULT __stdcall AwtDragSource::GetProcessId(FORMATETC __RPC_FAR *pFormatEtc, STGMEDIUM __RPC_FAR *pmedium) {
-
+    AwtToolkit::GetInstance().eventNumber++;
     if ((pFormatEtc->tymed & TYMED_HGLOBAL) == 0) {
         return DV_E_TYMED;
     } else if (pFormatEtc->lindex != -1) {
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp	Fri Sep 30 22:57:41 2016 +0400
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp	Fri Sep 30 22:10:44 2016 +0300
@@ -334,6 +334,7 @@
     ::GetKeyboardState(m_lastKeyboardState);
 
     m_waitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
+    isInDoDragDropLoop = FALSE;
     eventNumber = 0;
 }
 
@@ -2752,7 +2753,12 @@
     AwtToolkit & tk = AwtToolkit::GetInstance();
     DWORD eventNumber = tk.eventNumber;
     tk.PostMessage(WM_SYNC_WAIT, 0, 0);
-    ::WaitForSingleObject(tk.m_waitEvent, INFINITE);
+    for(long t = 2; t < timeout &&
+               WAIT_TIMEOUT == ::WaitForSingleObject(tk.m_waitEvent, 2); t+=2) {
+        if (tk.isInDoDragDropLoop) {
+            break;
+        }
+    }
     DWORD newEventNumber = tk.eventNumber;
     return (newEventNumber - eventNumber) > 2;
 }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h	Fri Sep 30 22:57:41 2016 +0400
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h	Fri Sep 30 22:10:44 2016 +0300
@@ -388,7 +388,8 @@
     static BOOL activateKeyboardLayout(HKL hkl);
 
     HANDLE m_waitEvent;
-    DWORD eventNumber;
+    volatile DWORD eventNumber;
+    volatile BOOL isInDoDragDropLoop;
 private:
     HWND CreateToolkitWnd(LPCTSTR name);