/** * 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 }
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(); }
/** * 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]); }
/** * 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(); }
/** * 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(); }