/**
 * 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();
    }
}
Esempio n. 2
0
/**
 * 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);
            }
        }
    }
}
Esempio n. 3
0
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
  }
}