+/**
+ * Status bits to pass todo info from
+ * ptlrpc_main_check_event to ptlrpc_main.
+ */
+#define PTLRPC_MAIN_STOPPING 0x01
+#define PTLRPC_MAIN_IN_REQ 0x02
+#define PTLRPC_MAIN_ACTIVE_REQ 0x04
+#define PTLRPC_MAIN_CHECK_TIMED 0x08
+#define PTLRPC_MAIN_REPOST 0x10
+
+/**
+ * A container to share per-thread status variables between
+ * ptlrpc_main_check_event and ptlrpc_main functions.
+ */
+struct ptlrpc_main_check_s {
+ /** todo info for the ptrlrpc_main */
+ int todo;
+ /** is this thread counted as running or not? */
+ int running;
+};
+
+/**
+ * Check whether current service thread has work to do.
+ */
+static int ptlrpc_main_check_event(struct ptlrpc_thread *t,
+ struct ptlrpc_main_check_s *status)
+{
+ struct ptlrpc_service *svc = t->t_svc;
+ ENTRY;
+
+ status->todo = 0;
+
+ /* check the stop flags w/o any locking to make all
+ * concurrently running threads stop faster. */
+ if (unlikely((t->t_flags & SVC_STOPPING) ||
+ svc->srv_is_stopping)) {
+ status->todo |= PTLRPC_MAIN_STOPPING;
+ goto out;
+ }
+
+ cfs_spin_lock(&svc->srv_lock);
+ /* count this thread as not running before possible sleep in
+ * the outer wait event if it is not done yet. */
+ if (status->running) {
+ LASSERT(svc->srv_threads_running > 0);
+ svc->srv_threads_running--;
+ status->running = 0;
+ }
+ /* Process all incoming reqs before handling any */
+ if (!cfs_list_empty(&svc->srv_req_in_queue)) {
+ status->todo |= PTLRPC_MAIN_IN_REQ;
+ }
+ /* Don't handle regular requests in the last thread, in order
+ * to handle any incoming reqs, early replies, etc. */
+ if (ptlrpc_server_request_pending(svc, 0) &&
+ (svc->srv_threads_running < (svc->srv_threads_started - 1))) {
+ status->todo |= PTLRPC_MAIN_ACTIVE_REQ;
+ }
+ if (svc->srv_at_check) {
+ status->todo |= PTLRPC_MAIN_CHECK_TIMED;
+ }
+ if ((!cfs_list_empty(&svc->srv_idle_rqbds) &&
+ svc->srv_rqbd_timeout == 0)) {
+ status->todo |= PTLRPC_MAIN_REPOST;
+ }
+ /* count this thread as active if it goes out the outer
+ * wait event */
+ if (status->todo) {
+ svc->srv_threads_running++;
+ status->running = 1;
+ }
+ cfs_spin_unlock(&svc->srv_lock);
+ out:
+ RETURN(status->todo);
+}
+
+/**
+ * Main prlrpc service thread routine.
+ */