/**
 * Reports a fatal error that cannot be handled in Java.
 * Must be called from a KNI method
 *
 */
void handleFatalError(void) {
    KNI_StartHandles(1);
    KNI_DeclareHandle(throwableObj);
    KNI_GetParameterAsObject(1, throwableObj);

    /* IMPL NOTE: Figure out what throwable class this is and log the error? */
    REPORT_CRIT1(LC_CORE, "handleFatalError: uncaught exception in "
        "isolate %d event processing thread", getCurrentIsolateId());
    
    KNI_EndHandles();

    if (getCurrentIsolateId() == midpGetAmsIsolateId()) {
        /* AMS isolate or SVM mode, terminate VM */
        midp_exitVM(-1);
    } else {
        MidpEvent event;

        /* Application isolate, notify the AMS isolate. */
        MIDP_EVENT_INITIALIZE(event);
        event.type = FATAL_ERROR_NOTIFICATION;
        event.intParam1 = getCurrentIsolateId();

        /* Send the shutdown event. */
        StoreMIDPEventInVmThread(event, midpGetAmsIsolateId());
    }

    KNI_ReturnVoid();
}
/**
 * Helper function used by StoreMIDPEventInVmThread. Enqueues an event 
 * to be processed by the Java event thread for a given event queue.
 *
 * @param event the event to enqueue
 * @queueID ID of the queue to enqueue event from
 */
static void StoreMIDPEventInVmThreadImp(MidpEvent event, jint queueId) {
    EventQueue* pEventQueue;

    GET_EVENT_QUEUE_BY_ID(pEventQueue, queueId);

    midp_logThreadId("StoreMIDPEventInVmThread");

    midp_waitAndLockEventQueue();

    if (pEventQueue->numEvents != MAX_EVENTS) {

        pEventQueue->events[pEventQueue->eventIn] = event;
        pEventQueue->eventIn++;
        if (pEventQueue->eventIn == MAX_EVENTS) {
            /* This is a circular queue, so start back at zero. */
            pEventQueue->eventIn = 0;
        }
      
        pEventQueue->numEvents++;

        if (pEventQueue->isMonitorBlocked) {
            unblockMonitorThread(queueId);
        }
    } else {
        /*
         * Ignore the event; there is no space to store it.
         * IMPL NOTE: this should be fixed, or it should be a fatal error; 
         * dropping an event can lead to a full system deadlock.
         */
        REPORT_CRIT1(LC_CORE,"**event queue %d full, dropping event",
                     queueId); 
    }

    midp_unlockEventQueue();

#if ENABLE_EVENT_SPYING
    if (queueId != gsEventSpyingQueueId) {
        GET_EVENT_QUEUE_BY_ID(pEventQueue, gsEventSpyingQueueId);
        if (pEventQueue->isActive && event.type != EVENT_QUEUE_SHUTDOWN) {
            if (0 == duplicateMIDPEventFields(&event)) {
                StoreMIDPEventInVmThreadImp(event, gsEventSpyingQueueId); 
            } else {
                REPORT_CRIT(LC_CORE, 
                        "StoreMIDPEventInVmThread: Out of memory.");
                return;
            }
        }
    }
#endif
}
示例#3
0
static void StoreMIDPEventInVmThreadImp(MidpEvent event, int isolateId) {
    EventQueue* pEventQueue;
    JVMSPI_ThreadID thread;

    pEventQueue = getIsolateEventQueue(isolateId);

    midp_logThreadId("StoreMIDPEventInVmThread");

    midp_waitAndLockEventQueue();

    if (pEventQueue->numEvents != MAX_EVENTS) {

        pEventQueue->events[pEventQueue->eventIn] = event;
        pEventQueue->eventIn++;
        if (pEventQueue->eventIn == MAX_EVENTS) {
            /* This is a circular queue, so start back at zero. */
            pEventQueue->eventIn = 0;
        }
      
        pEventQueue->numEvents++;

        if (pEventQueue->isMonitorBlocked) {
            /*
             * The event monitor thread has been saved as the "special" thread
             * of this particular isolate in order to avoid having to search
             * the entire list of threads.
             */
            thread = SNI_GetSpecialThread(isolateId);
            if (thread != NULL) {
                midp_thread_unblock(thread);
                pEventQueue->isMonitorBlocked = KNI_FALSE;
            } else {
                REPORT_CRIT(LC_CORE,
                    "StoreMIDPEventInVmThread: cannot find "
                    "native event monitor thread");
            }
        }
    } else {
        /*
         * Ignore the event; there is no space to store it.
         * IMPL NOTE: this should be fixed, or it should be a fatal error; 
         * dropping an event can lead to a full system deadlock.
         */
        REPORT_CRIT1(LC_CORE,"**event queue %d full, dropping event",
                     isolateId); 
    }

    midp_unlockEventQueue();
}
示例#4
0
/**
 * Gets the event queue associated with an Isolate.
 *
 * @param isolateId ID of an Isolate or 0 for SVM mode
 *
 * @return an event queue
 */
static EventQueue* getIsolateEventQueue(int isolateId) {
    /*
     * Note: Using Isolate IDs as an event queue array index is only done
     * here for performance reasons and should NOT
     * be used in other parts of the system. In other parts of
     * the system something like a matching search should be used.
     */
    if (isolateId < 0 || isolateId >= maxIsolates) {
        REPORT_CRIT1(LC_CORE,
                     "Assertion failed: Isolate ID (%d) out of bounds",
                     isolateId);

        // avoid a SEGV;
        isolateId = 0;
    }

    return &(pEventQueues[isolateId]);
}
示例#5
0
/**
 * Releases any native resources used by the socket connection.
 * <p>
 * Java declaration:
 * <pre>
 *     finalize(V)V
 * </pre>
 */
KNIEXPORT KNI_RETURNTYPE_VOID
Java_com_sun_midp_io_j2me_socket_Protocol_finalize(void) {
    void *pcslHandle;
    int status = PCSL_NET_INVALID;
    void* context = NULL;

    KNI_StartHandles(1);
    KNI_DeclareHandle(thisObject);
    KNI_GetThisPointer(thisObject);

    pcslHandle = (void *)(getMidpSocketProtocolPtr(thisObject)->handle);

    REPORT_INFO1(LC_PROTOCOL, "socket::finalize handle=%d\n", pcslHandle);

    if (INVALID_HANDLE != pcslHandle) {
        status = pcsl_socket_close_start(pcslHandle, &context);

        getMidpSocketProtocolPtr(thisObject)->handle = (jint)INVALID_HANDLE;
        if (midpDecResourceCount(RSC_TYPE_TCP_CLI, 1) == 0) {
            REPORT_INFO(LC_PROTOCOL, "Resource limit update error"); 
        }

        if (status == PCSL_NET_IOERROR) { 
            midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE,
                    "IOError in socket::finalize error=%d\n", 
                    (int)pcsl_network_error(pcslHandle));
            REPORT_ERROR1(LC_PROTOCOL, "%s", gKNIBuffer);
        } else if (status == PCSL_NET_WOULDBLOCK) {
            /* blocking during finalize is not supported */
            REPORT_CRIT1(LC_PROTOCOL, "socket::finalize = 0x%x blocked\n", 
                         pcslHandle);
        }
    }
    FINISH_NETWORK_INDICATOR;

    KNI_EndHandles();
    KNI_ReturnVoid();
}
示例#6
0
/**
 * Native finalizer.
 * Releases all native resources used by this connection.
 */
KNIEXPORT KNI_RETURNTYPE_VOID
Java_com_sun_midp_io_j2me_btl2cap_L2CAPNotifierImpl_finalize(void) {
    javacall_handle handle, peer;
    int status = JAVACALL_FAIL;

    REPORT_INFO(LC_PROTOCOL, "btl2cap_notif::finalize");

    KNI_StartHandles(1);
    KNI_DeclareHandle(thisHandle);
    KNI_GetThisPointer(thisHandle);

    handle = (javacall_handle)KNI_GetIntField(thisHandle, notifHandleID);

    if (handle != BT_INVALID_HANDLE) {
        status = javacall_bt_l2cap_close(handle);

        KNI_SetIntField(thisHandle, notifHandleID, (jint)BT_INVALID_HANDLE);

        // Need revisit: add resource counting
/*
        if (midpDecResourceCount(RSC_TYPE_BT_SER, 1) == 0) {
            REPORT_INFO(LC_PROTOCOL, "Resource limit update error");
        }
*/

        if (status == JAVACALL_FAIL) {
            char* pError;
            javacall_bt_l2cap_get_error(handle, &pError);
            midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE,
                    "IO error in bt_l2cap_notif::finalize (%s)\n", pError);
            REPORT_ERROR(LC_PROTOCOL, gKNIBuffer);
        } else if (status == JAVACALL_WOULD_BLOCK) {
            /* blocking during finalize is not supported */
            REPORT_CRIT1(LC_PROTOCOL,
                "btl2cap_notif::finalize notifier blocked, handle = %d\n",
                handle);
        }
    }

    peer = (javacall_handle)KNI_GetIntField(thisHandle, peerHandleID);

    if (peer != BT_INVALID_HANDLE) {
        status = javacall_bt_l2cap_close(peer);

        KNI_SetIntField(thisHandle, peerHandleID, (jint)BT_INVALID_HANDLE);

        // Need revisit: add resource counting
/*
        if (midpDecResourceCount(RSC_TYPE_BT_CLI, 1) == 0) {
            REPORT_INFO(LC_PROTOCOL, "Resource limit update error");
        }
*/

        if (status == JAVACALL_FAIL) {
            char* pError;
            javacall_bt_l2cap_get_error(peer, &pError);
            midp_snprintf(gKNIBuffer, KNI_BUFFER_SIZE,
                    "IO error in bt_l2cap_notif::finalize (%s)\n", pError);
            REPORT_ERROR(LC_PROTOCOL, gKNIBuffer);
        } else if (status == JAVACALL_WOULD_BLOCK) {
            /* blocking during finalize is not supported */
            REPORT_CRIT1(LC_PROTOCOL,
                "btl2cap_notif::finalize blocked, handle = %d\n", peer);
        }
    }

    REPORT_INFO(LC_PROTOCOL, "btl2cap_notif::finalize done!");

    KNI_EndHandles();
    KNI_ReturnVoid();
}