| 57 | } |
| 58 | |
| 59 | void AsyncIoRendezvous::RecvAsync(uint64 key_hash, DoneCallback done) { |
| 60 | VLOG(2) << "Recv " << this << " " << key_hash; |
| 61 | |
| 62 | MutexedItemQueue* mq = nullptr; |
| 63 | { |
| 64 | mutex_lock l(mu_); |
| 65 | mq = table_.at(key_hash); |
| 66 | } |
| 67 | CHECK(mq); |
| 68 | ItemQueue* queue = &mq->queue; |
| 69 | mutex& mu = mq->mu; |
| 70 | mu.lock(); |
| 71 | if (queue->empty() || !queue->front()->IsSendValue()) { |
| 72 | // There is no message to pick up. |
| 73 | // Only recv-related fields need to be filled. |
| 74 | VLOG(2) << "Enqueue Recv Item (key hash:" << key_hash << "). "; |
| 75 | Item* item = new Item; |
| 76 | item->waiter = std::move(done); |
| 77 | |
| 78 | queue->push_back(item); |
| 79 | mu.unlock(); |
| 80 | return; |
| 81 | } |
| 82 | |
| 83 | VLOG(2) << "Consume Send Item (key hash:" << key_hash << "). "; |
| 84 | // A message has already arrived and is queued in the table under |
| 85 | // this key. Consumes the message and invokes the done closure. |
| 86 | Item* item = queue->front(); |
| 87 | queue->pop_front(); |
| 88 | mu.unlock(); |
| 89 | |
| 90 | // Invokes the done() by invoking its done closure, outside scope |
| 91 | // of the table lock. |
| 92 | CHECK(item->IsSendValue()); |
| 93 | done(Status::OK(), item->value); |
| 94 | delete item; |
| 95 | } |
| 96 | |
| 97 | /*static*/ AsyncIoRendezvous* GetXlaAsyncIORendezvous() { |
| 98 | static AsyncIoRendezvous* self = new AsyncIoRendezvous(); |