MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / blockForKeys

Function blockForKeys

src/blocked.cpp:654–697  ·  view source on GitHub ↗

Set a client in blocking mode for the specified key (list, zset or stream), * with the specified timeout. The 'type' argument is BLOCKED_LIST, * BLOCKED_ZSET or BLOCKED_STREAM depending on the kind of operation we are * waiting for an empty key in order to awake the client. The client is blocked * for all the 'numkeys' keys as in the 'keys' argument. When we block for * stream keys, we also p

Source from the content-addressed store, hash-verified

652 * be unblocked only when items with an ID greater or equal to the specified
653 * one is appended to the stream. */
654void blockForKeys(client *c, int btype, robj **keys, int numkeys, mstime_t timeout, robj *target, struct listPos *listpos, streamID *ids) {
655 dictEntry *de;
656 list *l;
657 int j;
658
659 c->bpop.timeout = timeout;
660 c->bpop.target = target;
661
662 if (listpos != NULL) c->bpop.listpos = *listpos;
663
664 if (target != NULL) incrRefCount(target);
665
666 for (j = 0; j < numkeys; j++) {
667 /* Allocate our bkinfo structure, associated to each key the client
668 * is blocked for. */
669 bkinfo *bki = (bkinfo*)zmalloc(sizeof(*bki));
670 if (btype == BLOCKED_STREAM)
671 bki->stream_id = ids[j];
672
673 /* If the key already exists in the dictionary ignore it. */
674 if (dictAdd(c->bpop.keys,keys[j],bki) != DICT_OK) {
675 zfree(bki);
676 continue;
677 }
678 incrRefCount(keys[j]);
679
680 /* And in the other "side", to map keys -> clients */
681 de = dictFind(c->db->blocking_keys,keys[j]);
682 if (de == NULL) {
683 int retval;
684
685 /* For every key we take a list of clients blocked for it */
686 l = listCreate();
687 retval = dictAdd(c->db->blocking_keys,keys[j],l);
688 incrRefCount(keys[j]);
689 serverAssertWithInfo(c,keys[j],retval == DICT_OK);
690 } else {
691 l = (list*)dictGetVal(de);
692 }
693 listAddNodeTail(l,c);
694 bki->listnode = listLast(l);
695 }
696 blockClient(c,btype);
697}
698
699/* Unblock a client that's waiting in a blocking operation such as BLPOP.
700 * You should never call this function directly, but unblockClient() instead. */

Callers 5

xreadCommandFunction · 0.85
moduleBlockClientFunction · 0.85
blmoveGenericCommandFunction · 0.85

Calls 8

incrRefCountFunction · 0.85
zmallocFunction · 0.85
zfreeFunction · 0.85
listCreateFunction · 0.85
listAddNodeTailFunction · 0.85
blockClientFunction · 0.85
dictAddFunction · 0.70
dictFindFunction · 0.70

Tested by

no test coverage detected