Publish a message */
| 292 | |
| 293 | /* Publish a message */ |
| 294 | int pubsubPublishMessage(robj *channel, robj *message) { |
| 295 | serverAssert(GlobalLocksAcquired()); |
| 296 | int receivers = 0; |
| 297 | dictEntry *de; |
| 298 | dictIterator *di; |
| 299 | listNode *ln; |
| 300 | listIter li; |
| 301 | |
| 302 | /* Send to clients listening for that channel */ |
| 303 | de = dictFind(g_pserver->pubsub_channels,channel); |
| 304 | if (de) { |
| 305 | list *list = reinterpret_cast<::list*>(dictGetVal(de)); |
| 306 | listNode *ln; |
| 307 | listIter li; |
| 308 | |
| 309 | listRewind(list,&li); |
| 310 | while ((ln = listNext(&li)) != NULL) { |
| 311 | client *c = reinterpret_cast<client*>(ln->value); |
| 312 | if (c->flags & CLIENT_CLOSE_ASAP) // avoid blocking if the write will be ignored |
| 313 | continue; |
| 314 | if (FCorrectThread(c)) |
| 315 | fastlock_lock(&c->lock); |
| 316 | addReplyPubsubMessage(c,channel,message); |
| 317 | if (FCorrectThread(c)) |
| 318 | fastlock_unlock(&c->lock); |
| 319 | receivers++; |
| 320 | } |
| 321 | } |
| 322 | /* Send to clients listening to matching channels */ |
| 323 | di = dictGetIterator(g_pserver->pubsub_patterns); |
| 324 | if (di) { |
| 325 | channel = getDecodedObject(channel); |
| 326 | while((de = dictNext(di)) != NULL) { |
| 327 | robj *pattern = (robj*)dictGetKey(de); |
| 328 | list *clients = (list*)dictGetVal(de); |
| 329 | if (!stringmatchlen(szFromObj(pattern), |
| 330 | sdslen(szFromObj(pattern)), |
| 331 | szFromObj(channel), |
| 332 | sdslen(szFromObj(channel)),0)) continue; |
| 333 | |
| 334 | listRewind(clients,&li); |
| 335 | while ((ln = listNext(&li)) != NULL) { |
| 336 | client *c = (client*)listNodeValue(ln); |
| 337 | if (c->flags & CLIENT_CLOSE_ASAP) |
| 338 | continue; |
| 339 | std::unique_lock<fastlock> l(c->lock, std::defer_lock); |
| 340 | if (FCorrectThread(c)) |
| 341 | l.lock(); |
| 342 | addReplyPubsubPatMessage(c,pattern,channel,message); |
| 343 | receivers++; |
| 344 | } |
| 345 | } |
| 346 | decrRefCount(channel); |
| 347 | dictReleaseIterator(di); |
| 348 | } |
| 349 | return receivers; |
| 350 | } |
| 351 |
no test coverage detected