Skip to content

Commit d62c39f

Browse files
committed
core: fix pipelined set failures on pending reads
- IO objects are enqueued per-worker-thread since a refactor in ec1fb56 - If a set payload is being read off the network but the read gets EAGAIN, _and_ there are already pending IO objects on the connection, the worker thread will execute the pending IOs - The worker resume code did not check for conn_nread state and would resume the connection's state machine if those IO's completed before the conn_nread state completes. - The connection state is now corrupt and will both leak memory and throw parsing errors. This is a one-line fix to avoid resuming the state machine if we were in conn_nread state, as well as avoiding finalizing a connection from the conn_closing state if there are pending suspended responses.
1 parent a5b3ce9 commit d62c39f

1 file changed

Lines changed: 8 additions & 4 deletions

File tree

memcached.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,8 @@ void conn_worker_readd(conn *c) {
551551
// any recursion here.
552552
event_active(&c->event, 0, 0);
553553
break;
554+
case conn_nread:
555+
// ran IO queue while waiting for set payload.
554556
case conn_write:
555557
case conn_mwrite:
556558
case conn_read:
@@ -3319,10 +3321,12 @@ static void drive_machine(conn *c) {
33193321
break;
33203322

33213323
case conn_closing:
3322-
if (IS_UDP(c->transport))
3323-
conn_cleanup(c);
3324-
else
3325-
conn_close(c);
3324+
if (!c->resps_suspended) {
3325+
if (IS_UDP(c->transport))
3326+
conn_cleanup(c);
3327+
else
3328+
conn_close(c);
3329+
}
33263330
stop = true;
33273331
break;
33283332

0 commit comments

Comments
 (0)