Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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.
- Loading branch information