Send a message and block on receive from the same thread When a Rendezvous is shared between multiple threads, for example a server, this ensures that the reply goes to the correct thread. 1. Empty -> SendReceiving, return (None, None) 3. Sending -> Sending, return (sending thread, None) Error returned to thread 2. Receiving -> Receiving, return (receiving thread, None) 3. SendReceiving -> SendR
(&mut self, thread: Box<Thread>, message: Message)
| 151 | /// 3. SendReceiving -> SendReceiving, return (sending thread, None) |
| 152 | /// Error returned to thread |
| 153 | pub fn send_receive(&mut self, thread: Box<Thread>, message: Message) |
| 154 | -> (Option<Box<Thread>>, Option<Box<Thread>>) { |
| 155 | match &*self { |
| 156 | Rendezvous::Empty => { |
| 157 | *self = Rendezvous::SendReceiving(thread, message); |
| 158 | (None, None) |
| 159 | } |
| 160 | Rendezvous::Sending(_, _) => { |
| 161 | // Signal error to thread: Can't have two sending threads |
| 162 | thread.return_error_message(syscalls::SYSCALL_ERROR_SEND_BLOCKING, message); |
| 163 | (Some(thread), None) |
| 164 | } |
| 165 | Rendezvous::Receiving(_, some_tid) => { |
| 166 | if let Some(tid) = some_tid { |
| 167 | // Restricted to a single thread |
| 168 | if thread.tid() != *tid { |
| 169 | // Wrong thread ID |
| 170 | thread.return_error_message(syscalls::SYSCALL_ERROR_RECV_BLOCKING, message); |
| 171 | return (Some(thread), None); |
| 172 | } |
| 173 | } |
| 174 | |
| 175 | // Complete the message transfer |
| 176 | if let Rendezvous::Receiving(rec_thread, _) = mem::replace(self, Rendezvous::Empty) { |
| 177 | rec_thread.return_message(message); |
| 178 | |
| 179 | // Calling thread waits for a reply |
| 180 | *self = Rendezvous::Receiving(thread, Some(rec_thread.tid())); |
| 181 | |
| 182 | return (Some(rec_thread), None); |
| 183 | } |
| 184 | (None, None) // This should never be reached |
| 185 | } |
| 186 | Rendezvous::SendReceiving(_, _) => { |
| 187 | // Signal error to thread: Can't have two sending threads |
| 188 | thread.return_error_message(syscalls::SYSCALL_ERROR_SEND_BLOCKING, message); |
| 189 | (Some(thread), None) |
| 190 | } |
| 191 | } |
| 192 | } |
| 193 | |
| 194 | /// Close a Rendezvous. |
| 195 | /// |
no test coverage detected