void JVMSPI_CheckEvents(JVMSPI_BlockedThreadInfo * blocked_threads, int blocked_threads_count, jlong timeout_milli_seconds) { // // Nothing to do on behalf of bsd sockets! // // Copy this function to your favorite place and // add your event checking code for any other stuff than bsd sockets. if (JVM_IsDebuggerActive()) { JVM_ProcessDebuggerCmds(); } #if NOT_CURRENTLY_USED // Enable this portion if you want to perform polling // with increasing timeouts #define MIN_POLL_MILLI_SECONDS 1 #define MAX_POLL_MILLI_SECONDS 5000 static int poll_interval_milli_seconds = MIN_POLL_MILLI_SECONDS; if (timeout_milli_seconds < 0) { // There seems to be no active thread right now // Poll in increasing intervals poll_interval_milli_seconds *= 2; if (poll_interval_milli_seconds > MAX_POLL_MILLI_SECONDS) { poll_interval_milli_seconds = MAX_POLL_MILLI_SECONDS; } timeout_milli_seconds = poll_interval_milli_seconds; } else { // We have encountered an active thread again // Reset the polling wait to minimum poll_interval_milli_seconds = MIN_POLL_MILLI_SECONDS; } #endif ANI_WaitForThreadUnblocking(blocked_threads, blocked_threads_count, timeout_milli_seconds); // Implement alternating polling by enabling the code above // and then adding your own checking code // for additional event sources here }
void JVMSPI_CheckEvents(JVMSPI_BlockedThreadInfo * blocked_threads, int blocked_threads_count, jlong timeout_milli_seconds) { fd_set read_fds; fd_set write_fds; fd_set except_fds; int i, num_fds, num_ready; bool debugger_active = JVM_IsDebuggerActive(); #if ENABLE_JAVA_DEBUGGER int dbg_socket_fd = -1; if (debugger_active) { dbg_socket_fd = JVM_GetDebuggerSocketFd(); } #endif FD_ZERO(&read_fds); FD_ZERO(&write_fds); FD_ZERO(&except_fds); // [1] Gather the FDs that we want to check event for num_fds = 1; for (i=0; i<blocked_threads_count; i++) { BlockingSocket *socket = (BlockingSocket *)blocked_threads[i].reentry_data; if (socket->check_flags & CHECK_READ) { FD_SET(socket->fd, &read_fds); } if (socket->check_flags & CHECK_WRITE) { FD_SET(socket->fd, &write_fds); } if (socket->check_flags & CHECK_EXCEPTION) { FD_SET(socket->fd, &except_fds); } if (num_fds < socket->fd) { num_fds = socket->fd; } } #if ENABLE_JAVA_DEBUGGER if (debugger_active) { if (dbg_socket_fd != -1) { FD_SET(dbg_socket_fd, &read_fds); if (num_fds < dbg_socket_fd) { num_fds = dbg_socket_fd; } } } #endif // [2] Call select() on the FDs, without appropriate timeout value if (timeout_milli_seconds < 0) { // Sleep forever until an event happens GUARANTEE(blocked_threads_count > 0, "can't sleep forever with no event sources!"); num_ready = jvm_select(num_fds+1, &read_fds, &write_fds, &except_fds, NULL); } else if (!debugger_active && blocked_threads_count == 0) { // It's better to call Os::sleep than select() with no fds -- WinSock // returns immediately with an error status if you don't pass any // fds. Os::sleep(timeout_milli_seconds); num_ready = 0; } else { jlong sec, usec; struct timeval timeout; sec = timeout_milli_seconds / 1000; usec = (timeout_milli_seconds % 1000) * 1000; if (msw(sec) <= 0) { timeout.tv_sec = lsw(sec); } else { // mmmm, are you sure you want to sleep so long?? timeout.tv_sec = 0x7fffffff; } timeout.tv_usec = lsw(usec); num_ready = jvm_select(num_fds+1, &read_fds, &write_fds, &except_fds, &timeout); } // [3] If a thread's FD is ready, change the thread's status to ready if (num_ready > 0) { for (i = 0; i < blocked_threads_count; i++) { BlockingSocket *socket = (BlockingSocket *)blocked_threads[i].reentry_data; jboolean is_ready = KNI_FALSE; if (socket->check_flags & CHECK_READ) { if (FD_ISSET(socket->fd, &read_fds)) { is_ready = KNI_TRUE; } } if (socket->check_flags & CHECK_WRITE) { if (FD_ISSET(socket->fd, &write_fds)) { is_ready = KNI_TRUE; } } if (socket->check_flags & CHECK_EXCEPTION) { if (FD_ISSET(socket->fd, &except_fds)) { // This happens only if a connect() call failed. Let's close // the socket and make sure open0() returns -1: // // Note to QA: this block needs more testing! jvm_shutdown(socket->fd, 2); closesocket(socket->fd); socket->fd = -1; is_ready = KNI_TRUE; } } if (is_ready) { SNI_UnblockThread(blocked_threads[i].thread_id); } } #if ENABLE_JAVA_DEBUGGER if (debugger_active) { if (FD_ISSET(dbg_socket_fd, &read_fds)) { JVM_ProcessDebuggerCmds(); } } #endif } }
void FOX_FASTCALL(midp_check_events)(jlonglong timeout) { #else void midp_check_events(JVMSPI_BlockedThreadInfo *blocked_threads, int blocked_threads_count, jlong timeout) { if (midp_waitWhileSuspended()) { /* System has been requested to resume. Returning control to VM * to perform java-side resume routines. Timeout may be too long * here or even -1, thus do not check other events this time. */ return; } #endif newSignal.waitingFor = NO_SIGNAL; newSignal.pResult = ADDR_ZERO; MIDP_EVENT_INITIALIZE(newMidpEvent); checkForSystemSignal(&newSignal, &newMidpEvent, timeout); switch (newSignal.waitingFor) { #if ENABLE_JAVA_DEBUGGER case VM_DEBUG_SIGNAL: if (midp_isDebuggerActive()) { JVM_ProcessDebuggerCmds(); } break; #endif // ENABLE_JAVA_DEBUGGER case AMS_SIGNAL: midpStoreEventAndSignalAms(newMidpEvent); break; case UI_SIGNAL: midpStoreEventAndSignalForeground(newMidpEvent); break; case NETWORK_READ_SIGNAL: #ifdef FEATURE_PHONEME FASTIVA_DBREAK(); #else if (eventUnblockJavaThread(blocked_threads, blocked_threads_count, newSignal.waitingFor, newSignal.descriptor, newSignal.status)) /* Processing is done in eventUnblockJavaThread. */; else if (findPushBlockedHandle(newSignal.descriptor) != 0) { /* The push system is waiting for a read on this descriptor */ midp_thread_signal_list(blocked_threads, blocked_threads_count, PUSH_SIGNAL, 0, 0); } #endif #if (ENABLE_JSR_120 || ENABLE_JSR_205) else jsr120_check_signal(newSignal.waitingFor, newSignal.descriptor); #endif break; case HOST_NAME_LOOKUP_SIGNAL: case NETWORK_WRITE_SIGNAL: #if (ENABLE_JSR_120 || ENABLE_JSR_205) if (!jsr120_check_signal(newSignal.waitingFor, newSignal.descriptor)) #endif #ifdef FEATURE_PHONEME FASTIVA_DBREAK(); #else midp_thread_signal_list(blocked_threads, blocked_threads_count, newSignal.waitingFor, newSignal.descriptor, newSignal.status); #endif break; case NETWORK_EXCEPTION_SIGNAL: #ifdef FEATURE_PHONEME FASTIVA_DBREAK(); #else /* Find both the read and write threads and signal the status. */ eventUnblockJavaThread(blocked_threads, blocked_threads_count, NETWORK_READ_SIGNAL, newSignal.descriptor, newSignal.status); eventUnblockJavaThread(blocked_threads, blocked_threads_count, NETWORK_WRITE_SIGNAL, newSignal.descriptor, newSignal.status); #endif return; case PUSH_ALARM_SIGNAL: #ifdef FEATURE_PHONEME FASTIVA_DBREAK(); #else if (findPushTimerBlockedHandle(newSignal.descriptor) != 0) { /* The push system is waiting for this alarm */ midp_thread_signal_list(blocked_threads, blocked_threads_count, PUSH_SIGNAL, 0, 0); } #endif break; #if (ENABLE_JSR_135 || ENABLE_JSR_234) case MEDIA_EVENT_SIGNAL: StoreMIDPEventInVmThread(newMidpEvent, newMidpEvent.MM_ISOLATE); eventUnblockJavaThread(blocked_threads, blocked_threads_count, MEDIA_EVENT_SIGNAL, newSignal.descriptor, newSignal.status); break; case MEDIA_SNAPSHOT_SIGNAL: eventUnblockJavaThread(blocked_threads, blocked_threads_count, MEDIA_SNAPSHOT_SIGNAL, newSignal.descriptor, newSignal.status); break; #endif #ifdef ENABLE_JSR_179 case JSR179_LOCATION_SIGNAL: midp_thread_signal_list(blocked_threads, blocked_threads_count, JSR179_LOCATION_SIGNAL, newSignal.descriptor, newSignal.status); break; #endif /* ENABLE_JSR_179 */ #if (ENABLE_JSR_120 || ENABLE_JSR_205) case WMA_SMS_READ_SIGNAL: case WMA_CBS_READ_SIGNAL: case WMA_MMS_READ_SIGNAL: case WMA_SMS_WRITE_SIGNAL: case WMA_MMS_WRITE_SIGNAL: jsr120_check_signal(newSignal.waitingFor, newSignal.descriptor); break; #endif #ifdef ENABLE_JSR_177 case CARD_READER_DATA_SIGNAL: midp_thread_signal_list(blocked_threads, blocked_threads_count, newSignal.waitingFor, newSignal.descriptor, newSignal.status); break; #endif /* ENABLE_JSR_177 */ default: break; } /* switch */ } /** * Runs the VM in either master or slave mode depending on the * platform. It does not return until the VM is finished. In slave mode * it will contain a system event loop. * * @param classPath string containing the class path * @param mainClass string containing the main class for the VM to run. * @param argc the number of arguments to pass to the main method * @param argv the arguments to pass to the main method * * @return exit status of the VM */ #if 0 int midpRunVm(JvmPathChar* classPath, char* mainClass, int argc, char** argv) { /* Master mode does not need VM time slice requests. */ midp_thread_set_timeslice_proc(ADDR_ZERO); return JVM_Start(classPath, mainClass, argc, argv); }
/* * This function is called by the VM periodically. It has to check if * any of the blocked threads are ready for execution, and call * SNI_UnblockThread() on those threads that are ready. * * Values for the <timeout> paramater: * >0 = Block until an event happens, or until <timeout> milliseconds * has elapsed. * 0 = Check the events sources but do not block. Return to the * caller immediately regardless of the status of the event sources. * -1 = Do not timeout. Block until an event happens. */ void midp_check_events(JVMSPI_BlockedThreadInfo *blocked_threads, int blocked_threads_count, jlong timeout) { if (midp_waitWhileSuspended()) { /* System has been requested to resume. Returning control to VM * to perform java-side resume routines. Timeout may be too long * here or even -1, thus do not check other events this time. */ return; } newSignal.waitingFor = 0; newSignal.pResult = NULL; MIDP_EVENT_INITIALIZE(newMidpEvent); checkForSystemSignal(&newSignal, &newMidpEvent, timeout); switch (newSignal.waitingFor) { #if ENABLE_JAVA_DEBUGGER case VM_DEBUG_SIGNAL: if (midp_isDebuggerActive()) { JVM_ProcessDebuggerCmds(); } break; #endif // ENABLE_JAVA_DEBUGGER case AMS_SIGNAL: midpStoreEventAndSignalAms(newMidpEvent); break; case UI_SIGNAL: midpStoreEventAndSignalForeground(newMidpEvent); break; case NETWORK_READ_SIGNAL: if (eventUnblockJavaThread(blocked_threads, blocked_threads_count, newSignal.waitingFor, newSignal.descriptor, newSignal.status)) /* Processing is done in eventUnblockJavaThread. */; else if (findPushBlockedHandle(newSignal.descriptor) != 0) { /* The push system is waiting for a read on this descriptor */ midp_thread_signal_list(blocked_threads, blocked_threads_count, PUSH_SIGNAL, 0, 0); } #if (ENABLE_JSR_120 || ENABLE_JSR_205) else jsr120_check_signal(newSignal.waitingFor, newSignal.descriptor); #endif break; case HOST_NAME_LOOKUP_SIGNAL: case NETWORK_WRITE_SIGNAL: #if (ENABLE_JSR_120 || ENABLE_JSR_205) if (!jsr120_check_signal(newSignal.waitingFor, newSignal.descriptor)) #endif midp_thread_signal_list(blocked_threads, blocked_threads_count, newSignal.waitingFor, newSignal.descriptor, newSignal.status); break; case NETWORK_EXCEPTION_SIGNAL: /* Find both the read and write threads and signal the status. */ eventUnblockJavaThread(blocked_threads, blocked_threads_count, NETWORK_READ_SIGNAL, newSignal.descriptor, newSignal.status); eventUnblockJavaThread(blocked_threads, blocked_threads_count, NETWORK_WRITE_SIGNAL, newSignal.descriptor, newSignal.status); return; case PUSH_ALARM_SIGNAL: if (findPushTimerBlockedHandle(newSignal.descriptor) != 0) { /* The push system is waiting for this alarm */ midp_thread_signal_list(blocked_threads, blocked_threads_count, PUSH_SIGNAL, 0, 0); } break; #if (ENABLE_JSR_135 || ENABLE_JSR_234) case MEDIA_EVENT_SIGNAL: StoreMIDPEventInVmThread(newMidpEvent, newMidpEvent.MM_ISOLATE); eventUnblockJavaThread(blocked_threads, blocked_threads_count, MEDIA_EVENT_SIGNAL, newSignal.descriptor, newSignal.status); break; case MEDIA_SNAPSHOT_SIGNAL: eventUnblockJavaThread(blocked_threads, blocked_threads_count, MEDIA_SNAPSHOT_SIGNAL, newSignal.descriptor, newSignal.status); break; #endif #ifdef ENABLE_JSR_179 case JSR179_LOCATION_SIGNAL: midp_thread_signal_list(blocked_threads, blocked_threads_count, JSR179_LOCATION_SIGNAL, newSignal.descriptor, newSignal.status); break; #endif /* ENABLE_JSR_179 */ #if (ENABLE_JSR_120 || ENABLE_JSR_205) case WMA_SMS_READ_SIGNAL: case WMA_CBS_READ_SIGNAL: case WMA_MMS_READ_SIGNAL: case WMA_SMS_WRITE_SIGNAL: case WMA_MMS_WRITE_SIGNAL: jsr120_check_signal(newSignal.waitingFor, newSignal.descriptor); break; #endif #ifdef ENABLE_JSR_177 case CARD_READER_DATA_SIGNAL: midp_thread_signal_list(blocked_threads, blocked_threads_count, newSignal.waitingFor, newSignal.descriptor, newSignal.status); break; #endif /* ENABLE_JSR_177 */ default: break; } /* switch */ }