+
+static int
+lnet_eq_wait_locked(int *timeout_ms)
+{
+ lnet_ni_t *eq_waitni = NULL;
+ int tms = *timeout_ms;
+ int wait;
+ struct timeval then;
+ struct timeval now;
+
+ if (the_lnet.ln_eq_waitni != NULL) {
+ /* I have a single NI that I have to call into, to get
+ * events queued, or to block. */
+ lnet_eq_wait_unlock();
+
+ lnet_net_lock(0);
+ eq_waitni = the_lnet.ln_eq_waitni;
+ if (unlikely(eq_waitni == NULL)) {
+ lnet_net_unlock(0);
+
+ lnet_eq_wait_lock();
+ return -1;
+ }
+
+ lnet_ni_addref_locked(eq_waitni, 0);
+ lnet_net_unlock(0);
+
+ if (tms <= 0) { /* even for tms == 0 */
+ (eq_waitni->ni_lnd->lnd_wait)(eq_waitni, tms);
+
+ } else {
+ gettimeofday(&then, NULL);
+
+ (eq_waitni->ni_lnd->lnd_wait)(eq_waitni, tms);
+
+ gettimeofday(&now, NULL);
+ tms -= (now.tv_sec - then.tv_sec) * 1000 +
+ (now.tv_usec - then.tv_usec) / 1000;
+ if (tms < 0)
+ tms = 0;
+ }
+
+ lnet_ni_decref(eq_waitni);
+ lnet_eq_wait_lock();
+ } else { /* w/o eq_waitni */
+# ifndef HAVE_LIBPTHREAD
+ /* If I'm single-threaded, LNET fails at startup if it can't
+ * set the_lnet.ln_eqwaitni correctly. */
+ LBUG();
+# else /* HAVE_LIBPTHREAD */
+ struct timespec ts;
+
+ if (tms == 0) /* don't want to wait and new event */
+ return -1;
+
+ if (tms < 0) {
+ lnet_eq_cond_wait(NULL);
+
+ } else {
+
+ gettimeofday(&then, NULL);
+
+ ts.tv_sec = then.tv_sec + tms / 1000;
+ ts.tv_nsec = then.tv_usec * 1000 +
+ (tms % 1000) * 1000000;
+ if (ts.tv_nsec >= 1000000000) {
+ ts.tv_sec++;
+ ts.tv_nsec -= 1000000000;
+ }
+
+ lnet_eq_cond_wait(&ts);
+
+ gettimeofday(&now, NULL);
+ tms -= (now.tv_sec - then.tv_sec) * 1000 +
+ (now.tv_usec - then.tv_usec) / 1000;
+ if (tms < 0)
+ tms = 0;
+ }
+# endif /* HAVE_LIBPTHREAD */
+ }
+
+ wait = tms != 0;
+ *timeout_ms = tms;
+
+ return wait;
+}
+
+#endif /* __KERNEL__ */
+
+
+/**
+ * Block the calling process until there's an event from a set of EQs or
+ * timeout happens.
+ *
+ * If an event handler is associated with the EQ, the handler will run before
+ * this function returns successfully, in which case the corresponding event
+ * is consumed.
+ *
+ * LNetEQPoll() provides a timeout to allow applications to poll, block for a
+ * fixed period, or block indefinitely.
+ *
+ * \param eventqs,neq An array of EQ handles, and size of the array.
+ * \param timeout_ms Time in milliseconds to wait for an event to occur on
+ * one of the EQs. The constant LNET_TIME_FOREVER can be used to indicate an
+ * infinite timeout.
+ * \param event,which On successful return (1 or -EOVERFLOW), \a event will
+ * hold the next event in the EQs, and \a which will contain the index of the
+ * EQ from which the event was taken.
+ *
+ * \retval 0 No pending event in the EQs after timeout.
+ * \retval 1 Indicates success.
+ * \retval -EOVERFLOW Indicates success (i.e., an event is returned) and that
+ * at least one event between this event and the last event obtained from the
+ * EQ indicated by \a which has been dropped due to limited space in the EQ.
+ * \retval -ENOENT If there's an invalid handle in \a eventqs.
+ */
+int
+LNetEQPoll(lnet_handle_eq_t *eventqs, int neq, int timeout_ms,
+ lnet_event_t *event, int *which)
+{
+ int wait = 1;
+ int rc;
+ int i;