public bool call(RosMessage req, ref RosMessage resp) { if (resp == null) { //instantiate null response IN CASE this call succeeds resp = RosMessage.Generate(req.MessageType.Replace("Request", "Response")); } CallInfo info = new CallInfo { req = req, resp = resp, success = false, finished = false }; bool immediate = false; lock ( call_queue_mutex ) { if (connection.dropped) { return(false); } if (call_queue.Count == 0 && header_written && header_read) { immediate = true; } call_queue.Enqueue(info); } if (immediate) { processNextCall(); } while (!info.finished) { ROS.Debug()($"[{ThisNode.Name}] info.finished_condition.WaitOne();"); info.finished_condition.WaitOne(); } if (info.success) { // response is only sent on success => don't try to deserialize on failure. resp.Deserialize(resp.Serialized); } if (!string.IsNullOrEmpty(info.exception)) { ROS.Error()($"[{ThisNode.Name}] Service call failed: service [{name}] responded with an error: {info.exception}"); } return(info.success); }
public async Task <(bool, RosMessage)> Call(RosMessage request) { if (request == null) { throw new ArgumentNullException(nameof(request)); } RosMessage response = RosMessage.Generate(request.MessageType.Replace("Request", "Response")); if (response == null) { throw new Exception("Response message generation failed."); } var queue = callQueue; try { var call = new CallInfo { Request = request, Response = response }; await queue.OnNext(call, cancel).ConfigureAwait(false); bool success = await call.AsyncResult.ConfigureAwait(false); if (success) { // response is only sent on success response.Deserialize(response.Serialized); } return(success, response); } catch (Exception e) { string message = $"Service call failed: service [{name}] responded with an error: {e.Message}"; ROS.Error()(message); return(false, null); } finally { if (!persistent) { queue.OnCompleted(); } } }
internal long HandleMessage( RosMessage msg, bool ser, bool nocopy, IDictionary <string, string> connectionHeader, PublisherLink link ) { RosMessage t = null; long drops = 0; TimeData receipt_time = ROS.GetTime().data; if (msg.Serialized != null) // will be null if self-subscribed { msg.Deserialize(msg.Serialized); } lock (gate) { foreach (CallbackInfo info in callbacks) { string ti = info.Helper.type; if (nocopy || ser) { t = msg; t.connection_header = msg.connection_header; t.Serialized = null; bool wasFull = false; bool nonconst_need_copy = callbacks.Count > 1; info.SubscriptionQueue.AddToCallbackQueue(info.Helper, t, nonconst_need_copy, ref wasFull, receipt_time); if (wasFull) { ++drops; } else { info.CallbackQueue.AddCallback(info.SubscriptionQueue, info.SubscriptionQueue); } } } } if (t != null && link.Latched) { LatchInfo li = new LatchInfo { Message = t, Link = link, ConnectionHeader = connectionHeader, ReceiptTime = receipt_time }; if (latchedMessages.ContainsKey(link)) { latchedMessages[link] = li; } else { latchedMessages.Add(link, li); } } return(drops); }