SUGGESTED FIX
Create a JNI global reference to 'cursor', pass it from one thread to another
and delete the global reference after use of it as early as possible.
--- awt_DnDDS.cpp Thu Sep 9 14:38:38 2004
***************
*** 66,71 ****
--- 66,73 ----
jobject peer = env->NewLocalRef(dragSource->GetPeer());
HCURSOR initialCursor = dragSource->SetCursor(sdrp->cursor);
+ env->DeleteGlobalRef(sdrp->cursor);
+
HRESULT res;
// StartDrag has caused dragSource->m_mutex to be held by our thread now
***************
*** 1539,1544 ****
--- 1541,1548 ----
JNIEXPORT void JNICALL Java_sun_awt_windows_WDragSourceContextPeer_doDragDrop(JNIEnv* env, jobject self, jlong nativeCtxt, jobject cursor) {
TRY;
+ cursor = env->NewGlobalRef(cursor);
+
AwtDragSource::StartDrag((AwtDragSource*)nativeCtxt, cursor);
CATCH_BAD_ALLOC;
###@###.### 2004-09-09
The previous fix is tricky: if the global reference 'sdrp->cursor' were deleted
somewhere in the end of the method _DoDragDrop(), there could be another JNI error
since 'sdrp' is an address of a struct allocated on the stack of the method
StartDrag() and the method StartDrag() returns.
Now, to make the code more straightforward, the struct is allocated in the heap
instead of the stack:
--- awt_DnDDS.cpp Thu Sep 9 16:53:44 2004
***************
*** 45,55 ****
*/
void AwtDragSource::StartDrag(AwtDragSource* self, jobject cursor) {
! StartDragRec sdr = {self, cursor};
AwtToolkit::GetInstance().WaitForSingleObject(self->m_mutex);
! AwtToolkit::GetInstance().InvokeFunctionLater((void (*)(void *))&AwtDragSource::_DoDragDrop, (void *)&sdr);
self->WaitUntilSignalled(FALSE);
}
--- 45,57 ----
*/
void AwtDragSource::StartDrag(AwtDragSource* self, jobject cursor) {
! StartDragRec* sdrp = new StartDragRec;
! sdrp->dragSource = self;
! sdrp->cursor = cursor;
AwtToolkit::GetInstance().WaitForSingleObject(self->m_mutex);
! AwtToolkit::GetInstance().InvokeFunctionLater((void (*)(void *))&AwtDragSource::_DoDragDrop, (void *)sdrp);
self->WaitUntilSignalled(FALSE);
}
***************
*** 66,71 ****
--- 68,76 ----
jobject peer = env->NewLocalRef(dragSource->GetPeer());
HCURSOR initialCursor = dragSource->SetCursor(sdrp->cursor);
+ env->DeleteGlobalRef(sdrp->cursor);
+ delete sdrp;
+
HRESULT res;
// StartDrag has caused dragSource->m_mutex to be held by our thread now
***************
*** 1539,1544 ****
--- 1544,1551 ----
JNIEXPORT void JNICALL Java_sun_awt_windows_WDragSourceContextPeer_doDragDrop(JNIEnv* env, jobject self, jlong nativeCtxt, jobject cursor) {
TRY;
+ cursor = env->NewGlobalRef(cursor);
+
AwtDragSource::StartDrag((AwtDragSource*)nativeCtxt, cursor);
CATCH_BAD_ALLOC;
###@###.### 2004-09-09
|