int strm_flags; /* stream flags */
struct stream *strm;
struct proxy *px;
- struct server *srv; /* the server we are waiting for, may be NULL */
+ struct server *srv; /* the server we are waiting for, may be NULL if don't care */
+ struct server *target; /* the server that was assigned, = srv except if srv==NULL */
struct list list; /* next pendconn */
__decl_hathreads(HA_SPINLOCK_T lock);
};
* otherwise it necessarily belongs to one of the other lists ; this may
* not be atomically checked under threads though ;
* - pendconn->px is never NULL if pendconn->list is not empty
- * - pendconn->sv is never NULL if pendconn->list is in the server's queue,
+ * - pendconn->srv is never NULL if pendconn->list is in the server's queue,
* and is always NULL if pendconn->list is in the backend's queue or empty.
+ * - pendconn->target is NULL while the element is queued, and points to the
+ * assigned server when the pendconn is picked.
*
* Threads complicate the design a little bit but rules remain simple :
* - a lock is present in the pendconn (pendconn->lock). This lock is
* - no single operation except the pendconn initialisation prior to the
* insertion are performed without a queue lock held.
*
- * - pendconn_grab_from_px() and pendconn_process_next_strm() assign ->srv so
- * that the stream knows what server to work with (via pendconn_dequeue()).
- * It's worth noting that this assignment complicates the detection of the
- * queue to be locked/unlocked.
+ * - pendconn_grab_from_px() and pendconn_process_next_strm() assign ->target
+ * so that the stream knows what server to work with (via
+ * pendconn_dequeue() which sets it on strm->target).
*
* - a pendconn doesn't switch between queues, it stays where it is.
*/
pendconn_found:
__pendconn_unlink(p);
p->strm_flags |= SF_ASSIGNED;
- p->srv = srv;
+ p->target = srv;
HA_ATOMIC_ADD(&srv->served, 1);
HA_ATOMIC_ADD(&srv->proxy->served, 1);
srv = objt_server(strm->target);
px = strm->be;
+ p->target = NULL;
p->srv = NULL;
p->px = px;
p->strm = strm;
continue;
__pendconn_unlink(p);
- p->srv = s;
+ p->target = s;
remote |= !(p->strm->task->thread_mask & tid_bit);
task_wakeup(p->strm->task, TASK_WOKEN_RES);
}
/* the pendconn must be dequeued now */
- if (p->srv)
- strm->target = &p->srv->obj_type;
+ if (p->target)
+ strm->target = &p->target->obj_type;
strm->flags &= ~(SF_DIRECT | SF_ASSIGNED | SF_ADDR_SET);
strm->flags |= p->strm_flags & (SF_DIRECT | SF_ASSIGNED | SF_ADDR_SET);