/** * A midp internal function that unblocks the given Java thread. This should * be called in preference to calling SNI_UnblockThread directly, since * depending upon how the VM is scheduled (master mode or slave mode) * additional work may need to be done. In particular, in slave mode, this * function will need to arrange for a VM time slice to occur quickly. * * @param thr the Java thread to unblock */ void midp_thread_unblock(JVMSPI_ThreadID thr) { /* * Tell the VM to unblock the thread, and then tell the platform-specific * code to schedule the VM. */ SNI_UnblockThread(thr); if (vm_thread_timeslice_proc != NULL) { vm_thread_timeslice_proc(); } }
/** * Scan the block thread data for every thread blocked * for a JSR211_SIGNAL block type with INVOKE status and unblock it. * For now, every blocked thread is awoken; it should * check if the thread is blocked for the requested application, * classname. * * @param the new status of the blocked thread; either * STATUS_CANCELLED or STATUS_OK */ static void unblockWaitingThreads(int newStatus) { int n; int i; JVMSPI_BlockedThreadInfo *blocked_threads = SNI_GetBlockedThreads(&n); const int status_mask = JSR211_INVOKE_OK | JSR211_INVOKE_CANCELLED; int st = newStatus==STATUS_OK ? JSR211_INVOKE_OK: JSR211_INVOKE_CANCELLED; for (i = 0; i < n; i++) { MidpReentryData *p = (MidpReentryData*)(blocked_threads[i].reentry_data); if (p == NULL) { continue; } if (p->waitingFor == JSR211_SIGNAL && (p->status | status_mask) != 0) { JVMSPI_ThreadID id = blocked_threads[i].thread_id; if (id != NULL) { p->status = st; SNI_UnblockThread(id); } } } }
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 } }