+static void
+vls_mt_acq_locks (vcl_locked_session_t * vls, vls_mt_ops_t op, int *locks_acq)
+{
+ vcl_worker_t *wrk = vcl_worker_get_current ();
+ vcl_session_t *s = 0;
+ int is_nonblk = 0;
+
+ if (vls)
+ {
+ s = vcl_session_get (wrk, vls->session_index);
+ if (PREDICT_FALSE (!s))
+ return;
+ is_nonblk = VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK);
+ }
+
+ switch (op)
+ {
+ case VLS_MT_OP_READ:
+ if (!is_nonblk)
+ is_nonblk = vcl_session_read_ready (s) != 0;
+ if (!is_nonblk)
+ {
+ vls_mt_mq_lock ();
+ *locks_acq |= VLS_MT_LOCK_MQ;
+ }
+ break;
+ case VLS_MT_OP_WRITE:
+ ASSERT (s);
+ if (!is_nonblk)
+ is_nonblk = vcl_session_write_ready (s) != 0;
+ if (!is_nonblk)
+ {
+ vls_mt_mq_lock ();
+ *locks_acq |= VLS_MT_LOCK_MQ;
+ }
+ break;
+ case VLS_MT_OP_XPOLL:
+ vls_mt_mq_lock ();
+ *locks_acq |= VLS_MT_LOCK_MQ;
+ break;
+ case VLS_MT_OP_SPOOL:
+ vls_mt_spool_lock ();
+ *locks_acq |= VLS_MT_LOCK_SPOOL;
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+vls_mt_rel_locks (int locks_acq)
+{
+ if (locks_acq & VLS_MT_LOCK_MQ)
+ vls_mt_mq_unlock ();
+ if (locks_acq & VLS_MT_LOCK_SPOOL)
+ vls_mt_create_unlock ();
+}
+
+#define vls_mt_guard(_vls, _op) \
+ int _locks_acq = 0; \
+ if (PREDICT_FALSE (vcl_get_worker_index () == ~0)) \
+ vls_mt_add (); \
+ if (PREDICT_FALSE (vlsl->vls_mt_n_threads > 1)) \
+ vls_mt_acq_locks (_vls, _op, &_locks_acq); \
+
+#define vls_mt_unguard() \
+ if (PREDICT_FALSE (_locks_acq)) \
+ vls_mt_rel_locks (_locks_acq)
+