コード例 #1
0
        bool release(JNIEnv *env, jint mode=0)
        {
            Logger::log(LOG_DEBUGTRACE, "Releasing    PointersArrayPointerData       %p\n", startPointer);

            jobjectArray pointersArray = (jobjectArray)env->GetObjectField(
                nativePointerObject, Pointer_pointers);
            long size = (long)env->GetArrayLength(pointersArray);

            void **localPointer = (void**)startPointer;
            if (mode != JNI_ABORT)
            {
                // Write back the values from the native pointers array
                // into the Java objects
                for (int i=0; i<size; i++)
                {
                    jobject p = env->GetObjectArrayElement(pointersArray, i);
                    if (env->ExceptionCheck())
                    {
                        return false;
                    }
                    if (p != NULL)
                    {
                        // Check whether the value inside the pointer array has changed.
                        void *oldLocalPointer = arrayPointerDatas[i]->getPointer(env);

                        Logger::log(LOG_DEBUGTRACE, "About to write back pointer %d in PointersArrayPointerData\n", i);
                        Logger::log(LOG_DEBUGTRACE, "Old local pointer was %p\n", oldLocalPointer);
                        Logger::log(LOG_DEBUGTRACE, "New local pointer is  %p\n", localPointer[i]);

                        if (localPointer[i] != oldLocalPointer)
                        {
                            Logger::log(LOG_DEBUGTRACE, "In pointer %d setting value %p\n", i, localPointer[i]);
                            bool pointerUpdated = arrayPointerDatas[i]->setNewNativePointerValue(env, (jlong)localPointer[i]);
                            if (!pointerUpdated)
                            {
                                // If the pointer value could not be updated,
                                // (see setNewNativePointerValue documentation)
                                // then there is a pending IllegalArgumentException
                                return false;
                            }
                        }
                    }
                    else if (localPointer[i] != NULL)
                    {
                        // TODO: In future versions, it might be necessary to instantiate
                        // a pointer object here
                        ThrowByName(env, "java/lang/NullPointerException",
                            "Pointer points to an array containing a 'null' entry");
                        return false;
                    }
                }
            }

            // Release the PointerDatas for the pointer objects that
            // the pointer points to
            if (arrayPointerDatas != NULL)
            {
                for (int i=0; i<size; i++)
                {
                    if (arrayPointerDatas[i] != NULL)
                    {
                        if (!releasePointerData(env, arrayPointerDatas[i], mode)) return false;
                    }
                }
                delete[] arrayPointerDatas;
            }
            delete[] localPointer;

            env->DeleteGlobalRef(nativePointerObject);
            return true;
        }
コード例 #2
0
ファイル: PointerUtils.cpp プロジェクト: blueberry/JOCL
/**
 * Release the given PointerData and deletes the PointerData object.
 *
 * If the pointerObject of the given pointerData is NULL, the method simply
 * deletes the pointerData, sets it to NULL and returns true.
 *
 * Otherwise, the actions are depending on the memoryType of the pointerData:
 *
 * - For NATIVE or DIRECT memory, only the global reference to the
 *   Java pointer object is released
 * - For ARRAY memory, the respective java primitive array will be released
 * - For ARRAY_COPY memory, the respective java primitive array will be
 *   released, and the memory will be copied back (except when the given
 *   mode is JNI_ABORT)
 * - For POINTERS memory, the values of the pointers will be written
 *   back into the nativePointer field of the corresponding Java pointers.
 *
 * The method returns whether the respective operation succeeded.
 */
bool releasePointerData(JNIEnv *env, PointerData* &pointerData, jint mode)
{
    if (pointerData->memoryType == NATIVE || pointerData->memoryType == DIRECT)
    {
        Logger::log(LOG_DEBUGTRACE, "Releasing pointer data for direct or native data\n");

        env->DeleteGlobalRef(pointerData->pointerObject);
        delete pointerData;
        pointerData = NULL;
        return true;
    }
    else if (pointerData->memoryType == ARRAY_COPY)
    {
        Logger::log(LOG_DEBUGTRACE, "Releasing host memory from copied array in java buffer\n");

        env->ReleasePrimitiveArrayCritical(pointerData->array, (void*)pointerData->startPointer, mode);

        env->DeleteGlobalRef(pointerData->pointerObject);
        env->DeleteGlobalRef(pointerData->array);
        delete pointerData;
        pointerData = NULL;
        return true;
    }
    else if (pointerData->memoryType == ARRAY)
    {
        Logger::log(LOG_DEBUGTRACE, "Releasing host memory from array in java buffer\n");

        env->ReleasePrimitiveArrayCritical(pointerData->array, (void*)pointerData->startPointer, JNI_ABORT);

        env->DeleteGlobalRef(pointerData->pointerObject);
        env->DeleteGlobalRef(pointerData->array);
        delete pointerData;
        pointerData = NULL;
        return true;
    }
    else if (pointerData->memoryType == POINTERS)
    {
        Logger::log(LOG_DEBUGTRACE, "Releasing host memory of pointers\n");

        // Write the data from the host pointer back into the
        // Java pointers in the pointer array
        jobjectArray pointersArray = (jobjectArray)env->GetObjectField(
            pointerData->pointerObject, NativePointerObject_pointers);
        jsize size = env->GetArrayLength(pointersArray);
        void **localPointer = (void**)pointerData->startPointer;
        for (int i=0; i<size; i++)
        {
            // Obtain the native pointer object at the current index,
            // and set its nativePointer value to the value from the
            // native array
            jobject p = env->GetObjectArrayElement(pointersArray, i);
            if (env->ExceptionCheck())
            {
                return false;
            }

            if (p != NULL)
            {
                env->SetLongField(p, NativePointerObject_nativePointer, (jlong)localPointer[i]);
                env->SetLongField(p, NativePointerObject_byteOffset, 0);
            }
            else if (localPointer[i] != NULL)
            {
                // If the object at the target position is 'null', but
                // the value in the native array is not NULL, then try
                // to create the appropriate pointer object for the
                // target array and store the non-NULL value in the
                // created object
                if (!createPointerObject(env, pointersArray, i, localPointer[i]))
                {
                    return false;
                }
            }
        }

        // Release the PointerDatas for the pointer objects that
        // the pointer points to
        PointerData **localPointerDatas = pointerData->pointers;
        if (localPointerDatas != NULL)
        {
            for (int i=0; i<size; i++)
            {
                if (localPointerDatas[i] != NULL)
                {
                    if (!releasePointerData(env, localPointerDatas[i])) return false;
                }
            }
            delete[] localPointerDatas;
        }
        delete[] (void**)pointerData->startPointer;
        env->DeleteGlobalRef(pointerData->pointerObject);
        delete pointerData;
        pointerData = NULL;
        return true;
    }
    return true;
}