8006941: [macosx] Deadlock in drag and drop
authorpchelko
Fri, 05 Apr 2013 18:29:53 +0100
changeset 16710 f041f82cdeac
parent 16709 ee3542d637fe
child 16711 7a5dc9467315
8006941: [macosx] Deadlock in drag and drop 7199783: Setting cursor on DragSourceContext does not work on OSX Reviewed-by: anthony, serb
jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java
jdk/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java
jdk/src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java
jdk/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java
jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
jdk/src/macosx/native/sun/awt/CDragSource.h
jdk/src/macosx/native/sun/awt/CDragSource.m
jdk/src/macosx/native/sun/awt/CDragSourceContextPeer.m
jdk/src/macosx/native/sun/awt/CDropTarget.m
jdk/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java
jdk/test/java/awt/dnd/DisposeFrameOnDragCrash/DisposeFrameOnDragTest.java
--- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java	Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java	Fri Apr 05 18:29:53 2013 +0100
@@ -336,7 +336,7 @@
         return peerTreeLock;
     }
 
-    final T getTarget() {
+    public final T getTarget() {
         return target;
     }
 
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java	Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CCursorManager.java	Fri Apr 05 18:29:53 2013 +0100
@@ -51,15 +51,6 @@
 
     @Override
     protected Point getCursorPosition() {
-        synchronized(this) {
-            if (isDragging) {
-                // during the drag operation, the appkit thread is blocked,
-                // so nativeGetCursorPosition invocation may cause a deadlock.
-                // In order to avoid this, we returns last know cursor position.
-                return new Point(dragPos);
-            }
-        }
-
         final Point2D nativePosition = nativeGetCursorPosition();
         return new Point((int)nativePosition.getX(), (int)nativePosition.getY());
     }
@@ -101,31 +92,4 @@
         // do something special
         throw new RuntimeException("Unimplemented");
     }
-
-    // package private methods to handle cursor change during drag-and-drop
-    private boolean isDragging = false;
-    private Point dragPos = null;
-
-    synchronized void startDrag(int x, int y) {
-        if (isDragging) {
-            throw new RuntimeException("Invalid Drag state in CCursorManager!");
-        }
-        isDragging = true;
-        dragPos = new Point(x, y);
-    }
-
-    synchronized void updateDragPosition(int x, int y) {
-        if (!isDragging) {
-            throw new RuntimeException("Invalid Drag state in CCursorManager!");
-        }
-        dragPos.move(x, y);
-    }
-
-    synchronized void stopDrag() {
-        if (!isDragging) {
-            throw new RuntimeException("Invalid Drag state in CCursorManager!");
-        }
-        isDragging = false;
-        dragPos = null;
-    }
 }
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java	Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java	Fri Apr 05 18:29:53 2013 +0100
@@ -38,8 +38,12 @@
 import javax.accessibility.*;
 
 import java.util.Map;
+import java.util.concurrent.Callable;
+
 import sun.awt.dnd.*;
 import sun.lwawt.LWComponentPeer;
+import sun.lwawt.LWWindowPeer;
+import sun.lwawt.PlatformWindow;
 
 
 public final class CDragSourceContextPeer extends SunDragSourceContextPeer {
@@ -104,13 +108,8 @@
         }
 
         //It sure will be LWComponentPeer instance as rootComponent is a Window
-        LWComponentPeer peer = (LWComponentPeer)rootComponent.getPeer();
-        //Get a pointer to a native window
-        CPlatformWindow platformWindow = (CPlatformWindow) peer.getPlatformWindow();
-        long nativeWindowPtr = platformWindow.getNSWindowPtr();
-
-        // Get drag cursor:
-        Cursor cursor = this.getCursor();
+        PlatformWindow platformWindow = ((LWComponentPeer)rootComponent.getPeer()).getPlatformWindow();
+        long nativeViewPtr = CPlatformWindow.getNativeViewPtr(platformWindow);
 
         // If there isn't any drag image make one of default appearance:
         if (fDragImage == null)
@@ -139,19 +138,15 @@
 
         try {
             // Create native dragging source:
-            final long nativeDragSource = createNativeDragSource(component, peer, nativeWindowPtr, transferable, triggerEvent,
+            final long nativeDragSource = createNativeDragSource(component, nativeViewPtr, transferable, triggerEvent,
                 (int) (dragOrigin.getX()), (int) (dragOrigin.getY()), extModifiers,
-                clickCount, timestamp, cursor, fDragCImage, dragImageOffset.x, dragImageOffset.y,
+                clickCount, timestamp, fDragCImage, dragImageOffset.x, dragImageOffset.y,
                 getDragSourceContext().getSourceActions(), formats, formatMap);
 
             if (nativeDragSource == 0)
                 throw new InvalidDnDOperationException("");
 
             setNativeContext(nativeDragSource);
-
-            CCursorManager.getInstance().startDrag(
-                    (int) (dragOrigin.getX()),
-                    (int) (dragOrigin.getY()));
         }
 
         catch (Exception e) {
@@ -160,6 +155,8 @@
 
         SunDropTargetContextPeer.setCurrentJVMLocalSourceTransferable(transferable);
 
+        CCursorManager.getInstance().setCursor(getCursor());
+
         // Create a new thread to run the dragging operation since it's synchronous, only coming back
         // after dragging is finished. This leaves the AWT event thread free to handle AWT events which
         // are posted during dragging by native event handlers.
@@ -173,8 +170,6 @@
                     } catch (Exception e) {
                         e.printStackTrace();
                     } finally {
-                        CCursorManager.getInstance().stopDrag();
-
                         releaseNativeDragSource(nativeDragSource);
                         fDragImage = null;
                         if (fDragCImage != null) {
@@ -189,8 +184,6 @@
         }
 
         catch (Exception e) {
-            CCursorManager.getInstance().stopDrag();
-
             final long nativeDragSource = getNativeContext();
             setNativeContext(0);
             releaseNativeDragSource(nativeDragSource);
@@ -416,13 +409,24 @@
                                 final int modifiers,
                                 final int x, final int y) {
 
-        CCursorManager.getInstance().updateDragPosition(x, y);
+        try {
+            Component componentAt = LWCToolkit.invokeAndWait(
+                    new Callable<Component>() {
+                        @Override
+                        public Component call() {
+                            LWWindowPeer mouseEventComponent = LWWindowPeer.getWindowUnderCursor();
+                            if (mouseEventComponent == null) {
+                                return null;
+                            }
+                            Component root = SwingUtilities.getRoot(mouseEventComponent.getTarget());
+                            if (root == null) {
+                                return null;
+                            }
+                            Point rootLocation = root.getLocationOnScreen();
+                            return getDropTargetAt(root, x - rootLocation.x, y - rootLocation.y);
+                        }
+                    }, getComponent());
 
-        Component rootComponent = SwingUtilities.getRoot(getComponent());
-        if(rootComponent != null) {
-            Point componentPoint = new Point(x, y);
-            SwingUtilities.convertPointFromScreen(componentPoint, rootComponent);
-            Component componentAt = SwingUtilities.getDeepestComponentAt(rootComponent, componentPoint.x, componentPoint.y);
             if(componentAt != hoveringComponent) {
                 if(hoveringComponent != null) {
                     dragExit(x, y);
@@ -432,20 +436,36 @@
                 }
                 hoveringComponent = componentAt;
             }
+
+            postDragSourceDragEvent(targetActions, modifiers, x, y,
+                    DISPATCH_MOUSE_MOVED);
+        } catch (Exception e) {
+            throw new InvalidDnDOperationException("Failed to handle DragMouseMoved event");
         }
-        postDragSourceDragEvent(targetActions, modifiers, x, y,
-                                DISPATCH_MOUSE_MOVED);
     }
 
-    /**
-     * upcall from native code
-     */
-    private void dragEnter(final int targetActions,
-                           final int modifiers,
-                           final int x, final int y) {
-        CCursorManager.getInstance().updateDragPosition(x, y);
+    //Returns the first lightweight or heavyweight Component which has a dropTarget ready to accept the drag
+    //Should be called from the EventDispatchThread
+    private static Component getDropTargetAt(Component root, int x, int y) {
+        if (!root.contains(x, y) || !root.isEnabled() || !root.isVisible()) {
+            return null;
+        }
+
+        if (root.getDropTarget() != null && root.getDropTarget().isActive()) {
+            return root;
+        }
 
-        postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_ENTER);
+        if (root instanceof Container) {
+            for (Component comp : ((Container) root).getComponents()) {
+                Point loc = comp.getLocation();
+                Component dropTarget = getDropTargetAt(comp, x - loc.x, y - loc.y);
+                if (dropTarget != null) {
+                    return dropTarget;
+                }
+            }
+        }
+
+        return null;
     }
 
     /**
@@ -455,19 +475,15 @@
         hoveringComponent = null;
     }
 
-    public void setCursor(Cursor c) throws InvalidDnDOperationException {
-        // TODO : BG
-        //AWTLockAccess.awtLock();
-        super.setCursor(c);
-        //AWTLockAccess.awtUnlock();
+    @Override
+    protected void setNativeCursor(long nativeCtxt, Cursor c, int cType) {
+        CCursorManager.getInstance().setCursor(c);
     }
 
-    protected native void setNativeCursor(long nativeCtxt, Cursor c, int cType);
-
     // Native support:
-    private native long createNativeDragSource(Component component, ComponentPeer peer, long nativePeer, Transferable transferable,
+    private native long createNativeDragSource(Component component, long nativePeer, Transferable transferable,
         InputEvent triggerEvent, int dragPosX, int dragPosY, int extModifiers, int clickCount, long timestamp,
-        Cursor cursor, CImage nsDragImage, int dragImageOffsetX, int dragImageOffsetY,
+        CImage nsDragImage, int dragImageOffsetX, int dragImageOffsetY,
         int sourceActions, long[] formats, Map formatMap);
 
     private native void doDragging(long nativeDragSource);
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java	Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CDropTarget.java	Fri Apr 05 18:29:53 2013 +0100
@@ -30,6 +30,7 @@
 import java.awt.dnd.DropTarget;
 
 import sun.lwawt.LWComponentPeer;
+import sun.lwawt.PlatformWindow;
 
 
 public final class CDropTarget {
@@ -50,21 +51,11 @@
         fComponent = component;
         fPeer = peer;
 
-        // Make sure the drop target is a ComponentModel:
-        if (!(peer instanceof LWComponentPeer))
-            throw new IllegalArgumentException("CDropTarget's peer must be a LWComponentPeer.");
-
-        // Get model pointer (CButton.m and such) and its native peer:
-        LWComponentPeer model = (LWComponentPeer) peer;
-        if (model.getPlatformWindow() instanceof CPlatformWindow) {
-            CPlatformWindow platformWindow = (CPlatformWindow) model.getPlatformWindow();
-            long nativePeer = platformWindow.getNSWindowPtr();
-
-            // Create native dragging destination:
-            fNativeDropTarget = this.createNativeDropTarget(dropTarget, component, peer, nativePeer);
-            if (fNativeDropTarget == 0) {
-                throw new IllegalStateException("CDropTarget.createNativeDropTarget() failed.");
-            }
+        long nativePeer = CPlatformWindow.getNativeViewPtr(((LWComponentPeer) peer).getPlatformWindow());
+        // Create native dragging destination:
+        fNativeDropTarget = this.createNativeDropTarget(dropTarget, component, peer, nativePeer);
+        if (fNativeDropTarget == 0) {
+            throw new IllegalStateException("CDropTarget.createNativeDropTarget() failed.");
         }
     }
 
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Fri Apr 05 18:29:53 2013 +0100
@@ -875,6 +875,21 @@
         }
     }
 
+    /**
+     * Helper method to get a pointer to the native view from the PlatformWindow.
+     */
+    static long getNativeViewPtr(PlatformWindow platformWindow) {
+        long nativePeer = 0L;
+        if (platformWindow instanceof CPlatformWindow) {
+            nativePeer = ((CPlatformWindow) platformWindow).getContentView().getAWTView();
+        } else if (platformWindow instanceof CViewPlatformEmbeddedFrame){
+            nativePeer = ((CViewPlatformEmbeddedFrame) platformWindow).getNSViewPtr();
+        } else {
+            throw new IllegalArgumentException("Unsupported platformWindow implementation");
+        }
+        return nativePeer;
+    }
+
     /*************************************************************
      * Callbacks from the AWTWindow and AWTView objc classes.
      *************************************************************/
--- a/jdk/src/macosx/native/sun/awt/CDragSource.h	Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/native/sun/awt/CDragSource.h	Fri Apr 05 18:29:53 2013 +0100
@@ -33,7 +33,6 @@
 @private
     NSView*        fView;
     jobject            fComponent;
-    jobject            fComponentPeer;
     jobject            fDragSourceContextPeer;
 
     jobject            fTransferable;
@@ -43,8 +42,6 @@
     jint                fClickCount;
     jint                fModifiers;
 
-    jobject            fCursor;
-
     NSImage*        fDragImage;
     NSPoint            fDragImageOffset;
 
@@ -59,12 +56,22 @@
 + (CDragSource *) currentDragSource;
 
 // Common methods:
-- (id)init:(jobject)jdragsourcecontextpeer component:(jobject)jcomponent peer:(jobject)jpeer control:(id)control
-    transferable:(jobject)jtransferable triggerEvent:(jobject)jtrigger
-    dragPosX:(jint)dragPosX dragPosY:(jint)dragPosY modifiers:(jint)extModifiers clickCount:(jint)clickCount timeStamp:(jlong)timeStamp
-    cursor:(jobject)jcursor
-    dragImage:(jobject)jnsdragimage dragImageOffsetX:(jint)jdragimageoffsetx dragImageOffsetY:(jint)jdragimageoffsety
-    sourceActions:(jint)jsourceactions formats:(jlongArray)jformats formatMap:(jobject)jformatmap;
+- (id)        init:(jobject)jDragSourceContextPeer
+         component:(jobject)jComponent
+           control:(id)control
+      transferable:(jobject)jTransferable
+      triggerEvent:(jobject)jTrigger
+          dragPosX:(jint)dragPosX
+          dragPosY:(jint)dragPosY
+         modifiers:(jint)extModifiers
+        clickCount:(jint)clickCount
+         timeStamp:(jlong)timeStamp
+         dragImage:(jobject)jDragImage
+  dragImageOffsetX:(jint)jDragImageOffsetX
+  dragImageOffsetY:(jint)jDragImageOffsetY
+     sourceActions:(jint)jSourceActions
+           formats:(jlongArray)jFormats
+         formatMap:(jobject)jFormatMap;
 
 - (void)removeFromView:(JNIEnv *)env;
 
--- a/jdk/src/macosx/native/sun/awt/CDragSource.m	Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/native/sun/awt/CDragSource.m	Fri Apr 05 18:29:53 2013 +0100
@@ -84,12 +84,22 @@
     return sCurrentDragSource;
 }
 
-- (id)init:(jobject)jdragsourcecontextpeer component:(jobject)jcomponent peer:(jobject)jpeer control:(id)control
-    transferable:(jobject)jtransferable triggerEvent:(jobject)jtrigger
-    dragPosX:(jint)dragPosX dragPosY:(jint)dragPosY modifiers:(jint)extModifiers clickCount:(jint)clickCount
-    timeStamp:(jlong)timeStamp cursor:(jobject)jcursor
-    dragImage:(jobject)jnsdragimage dragImageOffsetX:(jint)jdragimageoffsetx dragImageOffsetY:(jint)jdragimageoffsety
-    sourceActions:(jint)jsourceactions formats:(jlongArray)jformats formatMap:(jobject)jformatmap
+- (id)        init:(jobject)jDragSourceContextPeer
+         component:(jobject)jComponent
+           control:(id)control
+      transferable:(jobject)jTransferable
+      triggerEvent:(jobject)jTrigger
+          dragPosX:(jint)dragPosX
+          dragPosY:(jint)dragPosY
+         modifiers:(jint)extModifiers
+        clickCount:(jint)clickCount
+         timeStamp:(jlong)timeStamp
+         dragImage:(jobject)jDragImage
+  dragImageOffsetX:(jint)jDragImageOffsetX
+  dragImageOffsetY:(jint)jDragImageOffsetY
+     sourceActions:(jint)jSourceActions
+           formats:(jlongArray)jFormats
+         formatMap:(jobject)jFormatMap
 {
     self = [super init];
     DLog2(@"[CDragSource init]: %@\n", self);
@@ -100,27 +110,25 @@
     // Construct the object if we have a valid model for it:
     if (control != nil) {
         JNIEnv *env = [ThreadUtilities getJNIEnv];
-        fComponent = JNFNewGlobalRef(env, jcomponent);
-        fComponentPeer = JNFNewGlobalRef(env, jpeer);
-        fDragSourceContextPeer = JNFNewGlobalRef(env, jdragsourcecontextpeer);
+        fComponent = JNFNewGlobalRef(env, jComponent);
+        fDragSourceContextPeer = JNFNewGlobalRef(env, jDragSourceContextPeer);
 
-        fTransferable = JNFNewGlobalRef(env, jtransferable);
-        fTriggerEvent = JNFNewGlobalRef(env, jtrigger);
-        fCursor = JNFNewGlobalRef(env, jcursor);
+        fTransferable = JNFNewGlobalRef(env, jTransferable);
+        fTriggerEvent = JNFNewGlobalRef(env, jTrigger);
 
-        if (jnsdragimage) {
+        if (jDragImage) {
             JNF_MEMBER_CACHE(nsImagePtr, CImageClass, "ptr", "J");
-            jlong imgPtr = JNFGetLongField(env, jnsdragimage, nsImagePtr);
+            jlong imgPtr = JNFGetLongField(env, jDragImage, nsImagePtr);
             fDragImage = (NSImage*) jlong_to_ptr(imgPtr); // Double-casting prevents compiler 'd$|//
 
             [fDragImage retain];
         }
 
-        fDragImageOffset = NSMakePoint(jdragimageoffsetx, jdragimageoffsety);
+        fDragImageOffset = NSMakePoint(jDragImageOffsetX, jDragImageOffsetY);
 
-        fSourceActions = jsourceactions;
-        fFormats = JNFNewGlobalRef(env, jformats);
-        fFormatMap = JNFNewGlobalRef(env, jformatmap);
+        fSourceActions = jSourceActions;
+        fFormats = JNFNewGlobalRef(env, jFormats);
+        fFormatMap = JNFNewGlobalRef(env, jFormatMap);
 
         fTriggerEventTimeStamp = timeStamp;
         fDragPos = NSMakePoint(dragPosX, dragPosY);
@@ -129,9 +137,8 @@
 
         // Set this object as a dragging source:
 
-        AWTView *awtView = [((NSWindow *) control) contentView];
-        fView = [awtView retain];
-        [awtView setDragSource:self];
+        fView = [(AWTView *) control retain];
+        [fView setDragSource:self];
 
         // Let AWTEvent know Java drag is getting underway:
         [NSEvent javaDraggingBegin];
@@ -158,11 +165,6 @@
         fComponent = NULL;
     }
 
-    if (fComponentPeer != NULL) {
-        JNFDeleteGlobalRef(env, fComponentPeer);
-        fComponentPeer = NULL;
-    }
-
     if (fDragSourceContextPeer != NULL) {
         JNFDeleteGlobalRef(env, fDragSourceContextPeer);
         fDragSourceContextPeer = NULL;
@@ -178,11 +180,6 @@
         fTriggerEvent = NULL;
     }
 
-    if (fCursor != NULL) {
-        JNFDeleteGlobalRef(env, fCursor);
-        fCursor = NULL;
-    }
-
     if (fFormats != NULL) {
         JNFDeleteGlobalRef(env, fFormats);
         fFormats = NULL;
@@ -586,11 +583,6 @@
 {
     AWT_ASSERT_NOT_APPKIT_THREAD;
 
-    // Set the drag cursor (or not 3839999)
-    //JNIEnv *env = [ThreadUtilities getJNIEnv];
-    //jobject gCursor = JNFNewGlobalRef(env, fCursor);
-    //[EventFactory setJavaCursor:gCursor withEnv:env];
-
     [self performSelectorOnMainThread:@selector(doDrag) withObject:nil waitUntilDone:YES]; // AWT_THREADING Safe (called from unique asynchronous thread)
 }
 
--- a/jdk/src/macosx/native/sun/awt/CDragSourceContextPeer.m	Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/native/sun/awt/CDragSourceContextPeer.m	Fri Apr 05 18:29:53 2013 +0100
@@ -34,12 +34,13 @@
 /*
  * Class:     sun_lwawt_macosx_CDragSourceContextPeer
  * Method:    createNativeDragSource
- * Signature: (Ljava/awt/Component;Ljava/awt/peer/ComponentPeer;JLjava/awt/datatransfer/Transferable;Ljava/awt/event/InputEvent;IIIIJLjava/awt/Cursor;IJIII[JLjava/util/Map;)J
+ * Signature: (Ljava/awt/Component;JLjava/awt/datatransfer/Transferable;
+               Ljava/awt/event/InputEvent;IIIIJIJIII[JLjava/util/Map;)J
  */
 JNIEXPORT jlong JNICALL Java_sun_lwawt_macosx_CDragSourceContextPeer_createNativeDragSource
-  (JNIEnv *env, jobject jthis, jobject jcomponent, jobject jpeer, jlong jnativepeer, jobject jtransferable,
+  (JNIEnv *env, jobject jthis, jobject jcomponent, jlong jnativepeer, jobject jtransferable,
    jobject jtrigger, jint jdragposx, jint jdragposy, jint jextmodifiers, jint jclickcount, jlong jtimestamp,
-   jobject jcursor, jobject jnsdragimage, jint jdragimageoffsetx, jint jdragimageoffsety,
+   jobject jnsdragimage, jint jdragimageoffsetx, jint jdragimageoffsety,
    jint jsourceactions, jlongArray jformats, jobject jformatmap)
 {
     id controlObj = (id) jlong_to_ptr(jnativepeer);
@@ -47,12 +48,22 @@
 
 JNF_COCOA_ENTER(env);
     [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
-        dragSource = [[CDragSource alloc] init:jthis component:jcomponent peer:jpeer control:controlObj
-            transferable:jtransferable triggerEvent:jtrigger dragPosX:jdragposx
-            dragPosY:jdragposy modifiers:jextmodifiers clickCount:jclickcount timeStamp:jtimestamp
-            cursor:jcursor dragImage:jnsdragimage dragImageOffsetX:jdragimageoffsetx
-            dragImageOffsetY:jdragimageoffsety sourceActions:jsourceactions
-            formats:jformats formatMap:jformatmap];
+        dragSource = [[CDragSource alloc] init:jthis
+                                     component:jcomponent
+                                       control:controlObj
+                                  transferable:jtransferable
+                                  triggerEvent:jtrigger
+                                      dragPosX:jdragposx
+                                      dragPosY:jdragposy
+                                     modifiers:jextmodifiers
+                                    clickCount:jclickcount
+                                     timeStamp:jtimestamp
+                                     dragImage:jnsdragimage
+                              dragImageOffsetX:jdragimageoffsetx
+                              dragImageOffsetY:jdragimageoffsety
+                                 sourceActions:jsourceactions
+                                       formats:jformats
+                                     formatMap:jformatmap];
     }];
 JNF_COCOA_EXIT(env);
 
@@ -94,19 +105,3 @@
     [dragSource removeFromView:env];
 JNF_COCOA_EXIT(env);
 }
-
-/*
- * Class:     sun_lwawt_macosx_CDragSourceContextPeer
- * Method:    setNativeCursor
- * Signature: (JLjava/awt/Cursor;I)V
- */
-JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CDragSourceContextPeer_setNativeCursor
-  (JNIEnv *env, jobject jthis, jlong nativeDragSourceVal, jobject jcursor, jint jcursortype)
-{
-   //AWT_ASSERT_NOT_APPKIT_THREAD;
-
-//JNF_COCOA_ENTER(env);
-//    jobject gCursor = JNFNewGlobalRef(env, jcursor);
-//    [EventFactory setJavaCursor:gCursor withEnv:env];
-//JNF_COCOA_EXIT(env);
-}
--- a/jdk/src/macosx/native/sun/awt/CDropTarget.m	Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/macosx/native/sun/awt/CDropTarget.m	Fri Apr 05 18:29:53 2013 +0100
@@ -81,9 +81,8 @@
         fComponent = JNFNewGlobalRef(env, jcomponent);
         fDropTarget = JNFNewGlobalRef(env, jdropTarget);
 
-        AWTView *awtView = [((NSWindow *) control) contentView];
-        fView = [awtView retain];
-        [awtView setDropTarget:self];
+        fView = [((AWTView *) control) retain];
+        [fView setDropTarget:self];
 
 
     } else {
@@ -177,6 +176,10 @@
 {
     DLog2(@"[CDropTarget dealloc]: %@\n", self);
 
+    if(sCurrentDropTarget == self) {
+        sCurrentDropTarget = nil;
+    }
+
     [fView release];
     fView = nil;
 
@@ -490,7 +493,10 @@
         JNF_MEMBER_CACHE(handleEnterMessageMethod, jc_CDropTargetContextPeer, "handleEnterMessage", "(Ljava/awt/Component;IIII[JJ)I");
         if (sDraggingError == FALSE) {
             // Double-casting self gets rid of 'different size' compiler warning:
-            actions = JNFCallIntMethod(env, fDropTargetContextPeer, handleEnterMessageMethod, fComponent, (jint) javaLocation.x, (jint) javaLocation.y, dropAction, actions, formats, ptr_to_jlong(self)); // AWT_THREADING Safe (CToolkitThreadBlockedHandler)
+            // AWT_THREADING Safe (CToolkitThreadBlockedHandler)
+            actions = JNFCallIntMethod(env, fDropTargetContextPeer, handleEnterMessageMethod,
+                                       fComponent, (jint) javaLocation.x, (jint) javaLocation.y,
+                                       dropAction, actions, formats, ptr_to_jlong(self));
         }
 
         if (sDraggingError == FALSE) {
@@ -510,11 +516,6 @@
             // Remember the dragOp for no-op'd update messages:
             sUpdateOperation = dragOp;
         }
-
-        // If we are in the same process as the sender, make the sender post the appropriate message
-        if (sender) {
-            [[CDragSource currentDragSource] postDragEnter];
-        }
     }
 
     // 9-11-02 Note: the native event thread would not handle an exception gracefully:
@@ -608,11 +609,9 @@
         JNF_MEMBER_CACHE(handleExitMessageMethod, jc_CDropTargetContextPeer, "handleExitMessage", "(Ljava/awt/Component;J)V");
         if (sDraggingError == FALSE) {
             DLog3(@"  - dragExit: loc native %f, %f\n", sDraggingLocation.x, sDraggingLocation.y);
-            JNFCallVoidMethod(env, fDropTargetContextPeer, handleExitMessageMethod, fComponent, ptr_to_jlong(self)); // AWT_THREADING Safe (CToolkitThreadBlockedHandler)
-            // If we are in the same process as the sender, make the sender post the appropriate message
-            if (sender) {
-                [[CDragSource currentDragSource] postDragExit];
-            }
+             // AWT_THREADING Safe (CToolkitThreadBlockedHandler) 
+            JNFCallVoidMethod(env, fDropTargetContextPeer,
+                              handleExitMessageMethod, fComponent, ptr_to_jlong(self));
         }
 
         // 5-27-03 Note: [Radar 3270455]
--- a/jdk/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java	Wed Apr 03 20:54:26 2013 +0400
+++ b/jdk/src/share/classes/sun/awt/dnd/SunDragSourceContextPeer.java	Fri Apr 05 18:29:53 2013 +0100
@@ -278,7 +278,7 @@
      * upcall from native code
      */
 
-    private void dragEnter(final int targetActions,
+    protected void dragEnter(final int targetActions,
                            final int modifiers,
                            final int x, final int y) {
         postDragSourceDragEvent(targetActions, modifiers, x, y, DISPATCH_ENTER);
@@ -356,10 +356,6 @@
 
     public static void setDragDropInProgress(boolean b)
       throws InvalidDnDOperationException {
-        if (dragDropInProgress == b) {
-            throw new InvalidDnDOperationException(getExceptionMessage(b));
-        }
-
         synchronized (SunDragSourceContextPeer.class) {
             if (dragDropInProgress == b) {
                 throw new InvalidDnDOperationException(getExceptionMessage(b));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/dnd/DisposeFrameOnDragCrash/DisposeFrameOnDragTest.java	Fri Apr 05 18:29:53 2013 +0100
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2013, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test @summary JVM crash if the frame is disposed in DropTargetListener
+ * @author Petr Pchelko
+ * @library ../../regtesthelpers
+ * @build Util
+ * @compile DisposeFrameOnDragTest.java
+ * @run main/othervm DisposeFrameOnDragTest
+ */
+import java.awt.AWTException;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.dnd.DropTargetAdapter;
+import java.awt.dnd.DropTargetDragEvent;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.event.InputEvent;
+import java.lang.reflect.InvocationTargetException;
+import java.util.TooManyListenersException;
+import javax.swing.JFrame;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+import test.java.awt.regtesthelpers.Util;
+
+public class DisposeFrameOnDragTest {
+
+    private static JTextArea textArea;
+
+    public static void main(String[] args) throws Throwable {
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                constructTestUI();
+            }
+        });
+
+        Util.waitForIdle(null);
+        try {
+            Point loc = textArea.getLocationOnScreen();
+            Util.drag(new Robot(),
+                    new Point((int) loc.x + 3, (int) loc.y + 3),
+                    new Point((int) loc.x + 40, (int) loc.y + 40),
+                    InputEvent.BUTTON1_MASK);
+        } catch (AWTException ex) {
+            throw new RuntimeException("Could not initiate a drag operation");
+        }
+        Util.waitForIdle(null);
+    }
+
+    private static void constructTestUI() {
+        final JFrame frame = new JFrame("Test frame");
+        textArea = new JTextArea("Drag Me!");
+        try {
+            textArea.getDropTarget().addDropTargetListener(new DropTargetAdapter() {
+                @Override
+                public void drop(DropTargetDropEvent dtde) {
+                    //IGNORE
+                }
+
+                @Override
+                public void dragOver(DropTargetDragEvent dtde) {
+                    frame.dispose();
+                }
+            });
+        } catch (TooManyListenersException ex) {
+            throw new RuntimeException(ex);
+        }
+        textArea.setSize(100, 100);
+        textArea.setDragEnabled(true);
+        textArea.select(0, textArea.getText().length());
+        frame.add(textArea);
+        frame.setBounds(100, 100, 100, 100);
+        frame.setVisible(true);
+    }
+}