@@ -355,6 +355,63 @@ hsh_insert_busyobj(const struct worker *wrk, struct objhead *oh)
355355 return (oc );
356356}
357357
358+ /*---------------------------------------------------------------------
359+ */
360+
361+ static void
362+ hsh_waitlist (struct worker * wrk , struct req * req , struct objhead * oh )
363+ {
364+
365+ CHECK_OBJ_NOTNULL (wrk , WORKER_MAGIC );
366+ CHECK_OBJ_NOTNULL (req , REQ_MAGIC );
367+ CHECK_OBJ_NOTNULL (oh , OBJHEAD_MAGIC );
368+ Lck_AssertHeld (& oh -> mtx );
369+ AZ (req -> hash_ignore_busy );
370+ AZ (req -> hash_objhead );
371+
372+ DSLb (DBG_WAITINGLIST , "on waiting list <%p>" , oh );
373+
374+ /*
375+ * The objhead reference transfers to the sess, we get it
376+ * back when the sess comes off the waiting list and
377+ * calls us again
378+ */
379+ req -> hash_objhead = oh ;
380+ req -> wrk = NULL ;
381+ req -> waitinglist = 1 ;
382+
383+ if (req -> top -> topreq -> transport -> waitlist != NULL )
384+ req -> top -> topreq -> transport -> waitlist (wrk , req );
385+ }
386+
387+ static void
388+ hsh_reembark (struct worker * wrk , struct req * req )
389+ {
390+
391+ CHECK_OBJ_NOTNULL (wrk , WORKER_MAGIC );
392+ CHECK_OBJ_NOTNULL (req , REQ_MAGIC );
393+
394+ if (DO_DEBUG (DBG_WAITINGLIST ))
395+ VSLb (req -> vsl , SLT_Debug , "off waiting list" );
396+
397+ if (!IS_TOPREQ (req ) && req -> top -> topreq -> transport -> reembark != NULL )
398+ req -> top -> topreq -> transport -> reembark (wrk , req );
399+
400+ if (req -> transport -> reembark != NULL ) {
401+ // For ESI includes
402+ req -> transport -> reembark (wrk , req );
403+ return ;
404+ }
405+
406+ /*
407+ * We ignore the queue limits which apply to new
408+ * requests because if we fail to reschedule there
409+ * may be vmod_privs to cleanup and we need a proper
410+ * workerthread for that.
411+ */
412+ AZ (Pool_Task (req -> sp -> pool , req -> task , TASK_QUEUE_RUSH ));
413+ }
414+
358415/*---------------------------------------------------------------------
359416 */
360417
@@ -577,21 +634,11 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp)
577634
578635 /* There are one or more busy objects, wait for them */
579636 VTAILQ_INSERT_TAIL (& oh -> waitinglist , req , w_list );
637+ hsh_waitlist (wrk , req , oh );
580638
581- AZ (req -> hash_ignore_busy );
582-
583- /*
584- * The objhead reference transfers to the sess, we get it
585- * back when the sess comes off the waiting list and
586- * calls us again
587- */
588- req -> hash_objhead = oh ;
589- req -> wrk = NULL ;
590- req -> waitinglist = 1 ;
591-
592- if (DO_DEBUG (DBG_WAITINGLIST ))
593- VSLb (req -> vsl , SLT_Debug , "on waiting list <%p>" , oh );
594-
639+ /* NOTE OBS: We are going on the waitinglist. No changing of
640+ * anything on struct req after releasing the mutex, as we may be
641+ * rescheduled immediately. */
595642 Lck_Unlock (& oh -> mtx );
596643
597644 wrk -> stats -> busy_sleep ++ ;
@@ -648,19 +695,7 @@ hsh_rush2(struct worker *wrk, struct rush *r)
648695 req = VTAILQ_FIRST (& r -> reqs );
649696 CHECK_OBJ_NOTNULL (req , REQ_MAGIC );
650697 VTAILQ_REMOVE (& r -> reqs , req , w_list );
651- DSL (DBG_WAITINGLIST , req -> vsl -> wid , "off waiting list" );
652- if (req -> transport -> reembark != NULL ) {
653- // For ESI includes
654- req -> transport -> reembark (wrk , req );
655- } else {
656- /*
657- * We ignore the queue limits which apply to new
658- * requests because if we fail to reschedule there
659- * may be vmod_privs to cleanup and we need a proper
660- * workerthread for that.
661- */
662- AZ (Pool_Task (req -> sp -> pool , req -> task , TASK_QUEUE_RUSH ));
663- }
698+ hsh_reembark (wrk , req );
664699 }
665700}
666701
0 commit comments