| | |
| | | bool ShmMsgQueue::Send(const MQId &remote_id, const Msg &msg, const int timeout_ms) |
| | | { |
| | | Queue *remote = find(MsgQIdToName(remote_id)); |
| | | |
| | | return remote && remote->Write(msg, timeout_ms); |
| | | |
| | | if(!remote) { |
| | | return false; |
| | |
| | | |
| | | bool ShmMsgQueue::Send(const MQId &remote_id, const void *data, const size_t size, const int timeout_ms) |
| | | { |
| | | // Test shows that in the 2 cases: |
| | | // 1) build msg first, then find remote queue; |
| | | // 2) find remote queue first, then build msg; |
| | | // 1 is about 50% faster than 2, maybe cache related. |
| | | |
| | | Msg msg; |
| | | if (msg.Build(shm(), Id(), data, size, false)) { |
| | | if (Send(remote_id, msg, timeout_ms)) { |
| | | return true; |
| | | } else { |
| | | msg.FreeFrom(shm()); |
| | | if (msg.RemoveRef() == 0) { // works for both refcounted and not counted. |
| | | msg.FreeFrom(shm()); |
| | | } |
| | | } |
| | | } |
| | | return false; |
| | |
| | | { |
| | | Msg msg; |
| | | if (Read(msg, timeout_ms)) { |
| | | DEFER1(if (msg.RemoveRef() == 0) { msg.FreeFrom(shm()); }); |
| | | |
| | | auto ptr = msg.get<char>(); |
| | | if (ptr) { |
| | | DEFER1(shm().Dealloc(ptr);); |
| | | MsgMetaV1 meta; |
| | | meta.Parse(ptr); |
| | | source_id = meta.src_id_; |