Unblock a client that's waiting in a blocking operation such as BLPOP. * You should never call this function directly, but unblockClient() instead. */
| 676 | /* Unblock a client that's waiting in a blocking operation such as BLPOP. |
| 677 | * You should never call this function directly, but unblockClient() instead. */ |
| 678 | void unblockClientWaitingData(client *c) { |
| 679 | dictEntry *de; |
| 680 | dictIterator *di; |
| 681 | list *l; |
| 682 | |
| 683 | serverAssertWithInfo(c,NULL,dictSize(c->bpop.keys) != 0); |
| 684 | di = dictGetIterator(c->bpop.keys); |
| 685 | /* The client may wait for multiple keys, so unblock it for every key. */ |
| 686 | while((de = dictNext(di)) != NULL) { |
| 687 | robj *key = dictGetKey(de); |
| 688 | bkinfo *bki = dictGetVal(de); |
| 689 | |
| 690 | /* Remove this client from the list of clients waiting for this key. */ |
| 691 | l = dictFetchValue(c->db->blocking_keys,key); |
| 692 | serverAssertWithInfo(c,key,l != NULL); |
| 693 | listDelNode(l,bki->listnode); |
| 694 | /* If the list is empty we need to remove it to avoid wasting memory */ |
| 695 | if (listLength(l) == 0) |
| 696 | dictDelete(c->db->blocking_keys,key); |
| 697 | } |
| 698 | dictReleaseIterator(di); |
| 699 | |
| 700 | /* Cleanup the client structure */ |
| 701 | dictEmpty(c->bpop.keys,NULL); |
| 702 | if (c->bpop.target) { |
| 703 | decrRefCount(c->bpop.target); |
| 704 | c->bpop.target = NULL; |
| 705 | } |
| 706 | if (c->bpop.xread_group) { |
| 707 | decrRefCount(c->bpop.xread_group); |
| 708 | decrRefCount(c->bpop.xread_consumer); |
| 709 | c->bpop.xread_group = NULL; |
| 710 | c->bpop.xread_consumer = NULL; |
| 711 | } |
| 712 | } |
| 713 | |
| 714 | static int getBlockedTypeByType(int type) { |
| 715 | switch (type) { |
no test coverage detected