-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit 342cb92
committed
Rewrite async callback queue (push/shift) to not do allocations
The callback queue in the changed so that each callback is allocated once and
freed once. The operations "push" and "shift" don't copy the callback struct
between heap and stack, but instead they and just set the 'next' pointer to link
callbacks into a list, without doing any allocations. For pubsub channels, one
callback can be mapped to multiple channels, and they can be unsubscribed
independently, so we use a reference counter to keep track of references to a
callback.
This prepares for adding finalizer support and to be sure it is called only
once, when the callback is freed.
The way hiredis kept tack of 'pubsub mode' using `pending_subs` and
`unsubscribe_sent` was flawed. It couldn't handle multiple pending subscribe
commands with an overlapping but different set of channels and it couldn't
handle an error reply to a SUBSCRIBE or UNSUBSCRIBE command. Now we change this
so that all commands, even SUBSCRIBE and UNSUBSCRIBE, are added to the reply
queue and the 'subscribe' and 'unsubscribe' replies are matched against them in
the queue. The channel-to-callback dicts are updated when a 'subscribe' or
'unsubscribe' reply is received, confirming that the client has subscribed or
unsubscribed to a channel, rather than when the command is sent. This change
makes it possible to handle an error reply for a pubsub command.
With this change, there is no need to keep a different replies queue for
subscribe commands and regular commands. All are added to the same replies
queue.1 parent dedc620 commit 342cb92Copy full SHA for 342cb92
0 commit comments