/** * 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(); }
/** Unregisters current VM task from the list of listeners of record store changes */ void rms_registry_stop_record_store_listening(int suiteId, pcsl_string *storeName) { RecordStoreListener *listenerPtr; listenerPtr = findRecordStoreListener(suiteId, storeName); if (listenerPtr != NULL) { int i, count, taskId; count = listenerPtr->count; taskId = getCurrentIsolateId(); for (i = 0; i < count; i++) { if (listenerPtr->listenerId[i] == taskId) { if (--count == 0) { deleteListenerNode(listenerPtr); } else { listenerPtr->listenerId[i] = listenerPtr->listenerId[count]; } /* Remove notification counter of the task * not listening for any record store changes */ if (!hasRecordStoreListeners(taskId)) { removeNotificationCounter(taskId); } return; } } } }
/** Registeres current VM task to get notifications on record store changes */ void rms_registry_start_record_store_listening(int suiteId, pcsl_string *storeName) { RecordStoreListener *listenerPtr; int taskId = getCurrentIsolateId(); /* Cache maximal VM tasks number on first demand */ if (maxTasks == 0) { maxTasks = getMaxIsolates(); } /* Search for existing listener entry to update listener ID */ listenerPtr = findRecordStoreListener(suiteId, storeName); if (listenerPtr != NULL) { int i, count; count = listenerPtr->count; for (i = 0; i < count; i++) { if (listenerPtr->listenerId[i] == taskId) { return; } } if (count >= maxTasks) { REPORT_CRIT(LC_RMS, "rms_registry_start_record_store_listening: " "internal structure overflow"); return; } listenerPtr->listenerId[count] = taskId; listenerPtr->count = count + 1; return; } /* Create new listener entry for record store */ createListenerNode(suiteId, storeName, taskId); }
/** * Check whether current Isolate is an AMS Isolate * * @return true if the current Isolate is an AMS Isolate, * false otherwise. */ KNIEXPORT KNI_RETURNTYPE_BOOLEAN KNIDECL(com_sun_midp_main_MIDletSuiteUtils_isAmsIsolate) { #if ENABLE_MULTIPLE_ISOLATES KNI_ReturnBoolean(getCurrentIsolateId() == amsIsolateId); #else KNI_ReturnBoolean(KNI_TRUE); #endif }
/** * Reads a native event without blocking. * * @param event An empty event to be filled in if there is a queued * event. * @return <tt>true</tt> if an event was read, otherwise <tt>false</tt> */ KNIEXPORT KNI_RETURNTYPE_BOOLEAN Java_com_sun_midp_events_NativeEventMonitor_readNativeEvent(void) { jint isolateId; isolateId = getCurrentIsolateId(); KNI_ReturnBoolean(readNativeEventCommon(isolateId) != -1); }
/* * function javacall_amms_create_local_manager() * for details see declaration in javacall_multimedia_advanced.h */ javacall_result javacall_amms_create_local_manager( /*OUT*/ javacall_amms_local_manager_t** mgr ) { IGlobalManager *qs_mgr; javacall_amms_local_manager_t *ptr; if( NULL == mgr ) return JAVACALL_INVALID_ARGUMENT; ptr = malloc( sizeof(javacall_amms_local_manager_t) ); //ptr = malloc( sizeof( *ptr ) ); if( NULL == ptr ) return JAVACALL_OUT_OF_MEMORY; memset( ptr, 0, sizeof( javacall_amms_local_manager_t ) ); //memset( ptr, 0, sizeof( *ptr ) ); /* * Global manager access * * TODO: I'm using IsolateIdToGM( getCurrentIsolateId() ), but * AFAIK, MIDP API shouldn't be used in javacall... */ ptr->gmIdx = isolateIDtoGM( getCurrentIsolateId() ); qs_mgr = QSOUND_GET_GM( ptr->gmIdx ).gm; //printf( " GM : create gmIdx = %i\n", ptr->gmIdx ); reverb_init( &ptr->reverb, mQ234_GlobalManager_getReverbControl( qs_mgr ) ); equalizer_init( &ptr->equalizer, mQ234_GlobalManager_getEqualizerControl( qs_mgr ) ); ptr->volume.qs_obj_ptr = mQ234_GlobalManager_getVolumeControl( qs_mgr ); initSpectatorImpl( &ptr->spectator, ptr ); ptr->controls[0].type = javacall_music_eReverbControl; ptr->controls[0].ptr = &ptr->reverb; ptr->controls[1].type = javacall_amms_eVolumeControl; ptr->controls[1].ptr = &ptr->volume; ptr->controls[2].type = javacall_amms_eEqualizerControl; ptr->controls[2].ptr = &ptr->equalizer; ptr->controllable.controls = ptr->controls; ptr->controllable.number_of_controls = sizeof( ptr->controls ) / sizeof( ptr->controls[0] ); *mgr = ptr; return JAVACALL_OK; }
/** * Returns the native event queue handle for use by the native * finalizer. * * @return Native event queue handle */ KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_midp_events_EventQueue_getNativeEventQueueHandle(void){ jint queueId; EventQueue* pEventQueue; /* Use Isolate IDs for event queue handles. */ queueId = ISOLATE_ID_TO_QUEUE_ID(getCurrentIsolateId()); /* Mark queue as active */ GET_EVENT_QUEUE_BY_ID(pEventQueue, queueId); pEventQueue->isActive = KNI_TRUE; KNI_ReturnInt(queueId); }
/** * Sends a shutdown event to the event queue of the current Isolate. * */ KNIEXPORT KNI_RETURNTYPE_VOID Java_com_sun_midp_events_EventQueue_sendShutdownEvent(void) { MidpEvent event; jint isolateId; /* Initialize the event with just the SHUTDOWN type */ MIDP_EVENT_INITIALIZE(event); event.type = EVENT_QUEUE_SHUTDOWN; /* Send the shutdown event. */ isolateId = getCurrentIsolateId(); StoreMIDPEventInVmThread(event, isolateId); KNI_ReturnVoid(); }
/** Notifies registered record store listeneres about record store change */ void rms_registry_send_record_store_change_event( int suiteId, pcsl_string *storeName, int changeType, int recordId) { RecordStoreListener *listenerPtr; listenerPtr = findRecordStoreListener(suiteId, storeName); if (listenerPtr != NULL) { int i; pcsl_string_status rc; int taskId = getCurrentIsolateId(); for (i = 0; i < listenerPtr->count; i++) { int listenerId = listenerPtr->listenerId[i]; if (listenerId != taskId) { int counter; MidpEvent evt; int requiresAcknowledgment = 0; /* Request acknowledgment from receiver after sending a series * of notifications to protect receiver from queue overflow. */ counter = incNotificationCounter(listenerId); if (counter == RECORD_STORE_NOTIFICATION_QUEUE_SIZE / 2) { requiresAcknowledgment = 1; } MIDP_EVENT_INITIALIZE(evt); evt.type = RECORD_STORE_CHANGE_EVENT; evt.intParam1 = suiteId; evt.intParam2 = changeType; evt.intParam3 = recordId; evt.intParam4 = requiresAcknowledgment; rc = pcsl_string_dup(storeName, &evt.stringParam1); if (rc != PCSL_STRING_OK) { REPORT_CRIT(LC_RMS, "rms_registry_notify_record_store_change(): OUT OF MEMORY"); return; } StoreMIDPEventInVmThread(evt, listenerId); REPORT_INFO1(LC_RMS, "rms_registry_notify_record_store_change(): " "notify VM task %d of RMS changes", listenerId); } } } }
/** Fills list of listeners with pairs <listener ID, notification counter> */ void rms_registry_get_record_store_listeners( int suiteId, pcsl_string *storeName, int *listeners, int *length) { RecordStoreListener *listenerPtr; *length = 0; listenerPtr = findRecordStoreListener(suiteId, storeName); if (listenerPtr != NULL) { int i; int taskId = getCurrentIsolateId(); for (i = 0; i < listenerPtr->count; i++) { int listenerId = listenerPtr->listenerId[i]; if (listenerId != taskId) { int index = *length; listeners[index] = listenerId; listeners[index + 1] = getNotificationsCount(listenerId); *length += 2; } } } }
/** * Blocks the Java event thread until an event has been queued and returns * that event and the number of events still in the queue. * * @param event An empty event to be filled in if there is a queued * event. * * @return number of events waiting in the native queue */ KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_midp_events_NativeEventMonitor_waitForNativeEvent(void) { jint isolateId; int eventsPending; EventQueue* pEventQueue; isolateId = getCurrentIsolateId(); eventsPending = readNativeEventCommon(isolateId); if (eventsPending != -1) { /* event was read, and more may be pending */ KNI_ReturnInt(eventsPending); } pEventQueue = getIsolateEventQueue(isolateId); if (pEventQueue->isMonitorBlocked) { /* * ASSERT: we are about to block, so the state must not indicate * that a monitor thread is already blocked. */ REPORT_CRIT(LC_CORE, "Assertion failed: NativeEventMonitor.waitForNativeEvent " "called when Java thread already blocked"); } /* * Block the event processing thread. To speed up unblocking the * event monitor thread, this thread is saved as the "special" thread * of an Isolate to avoid having to search the entire list of threads. */ SNI_SetSpecialThread(isolateId); SNI_BlockThread(); pEventQueue->isMonitorBlocked = KNI_TRUE; KNI_ReturnInt(0); }
/** * Get the current Isolate ID. * * @return ID of the current Isolate */ KNIEXPORT KNI_RETURNTYPE_INT KNIDECL(com_sun_midp_main_MIDletSuiteUtils_getIsolateId) { KNI_ReturnInt(getCurrentIsolateId()); }
/** * Returns the native event queue handle for use by the native * finalizer. * * @return Native event queue handle */ KNIEXPORT KNI_RETURNTYPE_INT Java_com_sun_midp_events_EventQueue_getNativeEventQueueHandle(void) { /* For now use Isolate IDs for event queue handles. */ return getCurrentIsolateId(); }
/** * Clears native event queue for a given isolate - * there could be some events from isolate's previous usage. * */ KNIEXPORT KNI_RETURNTYPE_VOID Java_com_sun_midp_events_EventQueue_resetNativeEventQueue(void) { resetEventQueue(getCurrentIsolateId()); }