blob: 20231c4506b8bdd538cd16b8ec94032e3ee389cf [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Communication.cpp ---------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
14#include "lldb/lldb-private-log.h"
15#include "lldb/Core/Communication.h"
16#include "lldb/Core/Connection.h"
17#include "lldb/Core/Log.h"
18#include "lldb/Core/Timer.h"
19#include "lldb/Core/Event.h"
Greg Clayton7fb56d02011-02-01 01:31:41 +000020#include "lldb/Host/Host.h"
Eli Friedman88966972010-06-09 08:50:27 +000021#include <string.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022
23using namespace lldb;
24using namespace lldb_private;
25
Jim Ingham4bddaeb2012-02-16 06:50:00 +000026ConstString &
27Communication::GetStaticBroadcasterClass ()
28{
29 static ConstString class_name ("lldb.communication");
30 return class_name;
31}
32
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033//----------------------------------------------------------------------
34// Constructor
35//----------------------------------------------------------------------
Greg Claytond46c87a2010-12-04 02:39:47 +000036Communication::Communication(const char *name) :
Jim Ingham4bddaeb2012-02-16 06:50:00 +000037 Broadcaster (NULL, name),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000038 m_connection_sp (),
Eli Friedman8878f872010-07-09 22:53:18 +000039 m_read_thread (LLDB_INVALID_HOST_THREAD),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040 m_read_thread_enabled (false),
41 m_bytes(),
42 m_bytes_mutex (Mutex::eMutexTypeRecursive),
Greg Clayton7ec3d402011-01-27 09:02:32 +000043 m_write_mutex (Mutex::eMutexTypeNormal),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044 m_callback (NULL),
Caroline Tice82305fc2010-12-02 18:31:56 +000045 m_callback_baton (NULL),
Greg Claytond46c87a2010-12-04 02:39:47 +000046 m_close_on_eof (true)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047
48{
49 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
50 "%p Communication::Communication (name = %s)",
51 this, name);
Greg Clayton95bf0fd2011-04-01 00:29:43 +000052
53 SetEventName (eBroadcastBitDisconnected, "disconnected");
54 SetEventName (eBroadcastBitReadThreadGotBytes, "got bytes");
55 SetEventName (eBroadcastBitReadThreadDidExit, "read thread did exit");
56 SetEventName (eBroadcastBitReadThreadShouldExit, "read thread should exit");
57 SetEventName (eBroadcastBitPacketAvailable, "packet available");
Jim Ingham4bddaeb2012-02-16 06:50:00 +000058
59 CheckInWithManager();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060}
61
62//----------------------------------------------------------------------
63// Destructor
64//----------------------------------------------------------------------
65Communication::~Communication()
66{
67 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
68 "%p Communication::~Communication (name = %s)",
69 this, m_broadcaster_name.AsCString(""));
70 Clear();
71}
72
73void
74Communication::Clear()
75{
Greg Clayton756f8ae2011-08-19 23:28:37 +000076 SetReadThreadBytesReceivedCallback (NULL, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077 Disconnect (NULL);
Greg Clayton74d41932012-01-31 04:56:17 +000078 StopReadThread (NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000079}
80
81ConnectionStatus
Chris Lattner30fdc8d2010-06-08 16:52:24 +000082Communication::Connect (const char *url, Error *error_ptr)
83{
84 Clear();
85
86 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Connect (url = %s)", this, url);
87
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000088 lldb::ConnectionSP connection_sp (m_connection_sp);
89 if (connection_sp.get())
90 return connection_sp->Connect (url, error_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000091 if (error_ptr)
92 error_ptr->SetErrorString("Invalid connection.");
93 return eConnectionStatusNoConnection;
94}
95
96ConnectionStatus
97Communication::Disconnect (Error *error_ptr)
98{
99 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Disconnect ()", this);
100
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000101 lldb::ConnectionSP connection_sp (m_connection_sp);
102 if (connection_sp.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000103 {
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000104 ConnectionStatus status = connection_sp->Disconnect (error_ptr);
105 // We currently don't protect connection_sp with any mutex for
Greg Claytonbfae66a2010-12-12 21:50:57 +0000106 // multi-threaded environments. So lets not nuke our connection class
107 // without putting some multi-threaded protections in. We also probably
108 // don't want to pay for the overhead it might cause if every time we
109 // access the connection we have to take a lock.
110 //
Greg Claytone01e07b2013-04-18 18:10:51 +0000111 // This unique pointer will cleanup after itself when this object goes away,
Greg Claytonbfae66a2010-12-12 21:50:57 +0000112 // so there is no need to currently have it destroy itself immediately
113 // upon disconnnect.
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000114 //connection_sp.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000115 return status;
116 }
117 return eConnectionStatusNoConnection;
118}
119
120bool
121Communication::IsConnected () const
122{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000123 lldb::ConnectionSP connection_sp (m_connection_sp);
124 if (connection_sp.get())
125 return connection_sp->IsConnected ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000126 return false;
127}
128
129bool
130Communication::HasConnection () const
131{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000132 return m_connection_sp.get() != NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000133}
134
135size_t
136Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, ConnectionStatus &status, Error *error_ptr)
137{
138 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
Daniel Malead01b2952012-11-29 21:49:15 +0000139 "%p Communication::Read (dst = %p, dst_len = %" PRIu64 ", timeout = %u usec) connection = %p",
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000140 this,
141 dst,
Greg Clayton43e0af02012-09-18 18:04:04 +0000142 (uint64_t)dst_len,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000143 timeout_usec,
144 m_connection_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145
Stephen Wilsona08cfb12011-01-12 04:22:54 +0000146 if (m_read_thread_enabled)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000147 {
148 // We have a dedicated read thread that is getting data for us
149 size_t cached_bytes = GetCachedBytes (dst, dst_len);
150 if (cached_bytes > 0 || timeout_usec == 0)
151 {
152 status = eConnectionStatusSuccess;
153 return cached_bytes;
154 }
155
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000156 if (m_connection_sp.get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000157 {
158 if (error_ptr)
159 error_ptr->SetErrorString("Invalid connection.");
160 status = eConnectionStatusNoConnection;
161 return 0;
162 }
163 // Set the timeout appropriately
164 TimeValue timeout_time;
165 if (timeout_usec != UINT32_MAX)
166 {
167 timeout_time = TimeValue::Now();
168 timeout_time.OffsetWithMicroSeconds (timeout_usec);
169 }
170
171 Listener listener ("Communication::Read");
172 listener.StartListeningForEvents (this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit);
173 EventSP event_sp;
174 while (listener.WaitForEvent (timeout_time.IsValid() ? &timeout_time : NULL, event_sp))
175 {
176 const uint32_t event_type = event_sp->GetType();
177 if (event_type & eBroadcastBitReadThreadGotBytes)
178 {
179 return GetCachedBytes (dst, dst_len);
180 }
181
182 if (event_type & eBroadcastBitReadThreadDidExit)
183 {
184 Disconnect (NULL);
185 break;
186 }
187 }
188 return 0;
189 }
190
191 // We aren't using a read thread, just read the data synchronously in this
192 // thread.
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000193 lldb::ConnectionSP connection_sp (m_connection_sp);
194 if (connection_sp.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000195 {
Greg Clayton73bf5db2011-06-17 01:22:15 +0000196 return connection_sp->Read (dst, dst_len, timeout_usec, status, error_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000197 }
198
199 if (error_ptr)
200 error_ptr->SetErrorString("Invalid connection.");
201 status = eConnectionStatusNoConnection;
202 return 0;
203}
204
205
206size_t
207Communication::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr)
208{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000209 lldb::ConnectionSP connection_sp (m_connection_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000210
Jason Molendaccd41e52012-10-04 22:47:07 +0000211 Mutex::Locker locker(m_write_mutex);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000212 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
Daniel Malead01b2952012-11-29 21:49:15 +0000213 "%p Communication::Write (src = %p, src_len = %" PRIu64 ") connection = %p",
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000214 this,
215 src,
Greg Clayton43e0af02012-09-18 18:04:04 +0000216 (uint64_t)src_len,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000217 connection_sp.get());
218
219 if (connection_sp.get())
220 return connection_sp->Write (src, src_len, status, error_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000221
222 if (error_ptr)
223 error_ptr->SetErrorString("Invalid connection.");
224 status = eConnectionStatusNoConnection;
225 return 0;
226}
227
228
229bool
230Communication::StartReadThread (Error *error_ptr)
231{
Greg Clayton1cb64962011-03-24 04:28:38 +0000232 if (error_ptr)
233 error_ptr->Clear();
234
Greg Clayton2da6d492011-02-08 01:34:25 +0000235 if (IS_VALID_LLDB_HOST_THREAD(m_read_thread))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000236 return true;
237
238 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
239 "%p Communication::StartReadThread ()", this);
240
241
242 char thread_name[1024];
243 snprintf(thread_name, sizeof(thread_name), "<lldb.comm.%s>", m_broadcaster_name.AsCString());
244
Greg Clayton86c3f342010-09-15 05:19:45 +0000245 m_read_thread_enabled = true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000246 m_read_thread = Host::ThreadCreate (thread_name, Communication::ReadThread, this, error_ptr);
Greg Clayton2da6d492011-02-08 01:34:25 +0000247 if (!IS_VALID_LLDB_HOST_THREAD(m_read_thread))
Greg Clayton86c3f342010-09-15 05:19:45 +0000248 m_read_thread_enabled = false;
Greg Clayton26661bc2010-07-23 15:43:25 +0000249 return m_read_thread_enabled;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250}
251
252bool
253Communication::StopReadThread (Error *error_ptr)
254{
Greg Clayton2da6d492011-02-08 01:34:25 +0000255 if (!IS_VALID_LLDB_HOST_THREAD(m_read_thread))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000256 return true;
257
258 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
259 "%p Communication::StopReadThread ()", this);
260
261 m_read_thread_enabled = false;
262
263 BroadcastEvent (eBroadcastBitReadThreadShouldExit, NULL);
264
Greg Clayton74d41932012-01-31 04:56:17 +0000265 //Host::ThreadCancel (m_read_thread, error_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000266
Stephen Wilsona08cfb12011-01-12 04:22:54 +0000267 bool status = Host::ThreadJoin (m_read_thread, NULL, error_ptr);
Greg Clayton26661bc2010-07-23 15:43:25 +0000268 m_read_thread = LLDB_INVALID_HOST_THREAD;
Stephen Wilsona08cfb12011-01-12 04:22:54 +0000269 return status;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000270}
271
Greg Clayton59042602014-01-30 18:52:57 +0000272bool
273Communication::JoinReadThread (Error *error_ptr)
274{
275 if (!IS_VALID_LLDB_HOST_THREAD(m_read_thread))
276 return true;
277
278 bool success = Host::ThreadJoin (m_read_thread, NULL, error_ptr);
279 m_read_thread = LLDB_INVALID_HOST_THREAD;
280 return success;
281}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000282
283size_t
284Communication::GetCachedBytes (void *dst, size_t dst_len)
285{
286 Mutex::Locker locker(m_bytes_mutex);
287 if (m_bytes.size() > 0)
288 {
289 // If DST is NULL and we have a thread, then return the number
290 // of bytes that are available so the caller can call again
291 if (dst == NULL)
292 return m_bytes.size();
293
294 const size_t len = std::min<size_t>(dst_len, m_bytes.size());
295
Greg Clayton471b31c2010-07-20 22:52:08 +0000296 ::memcpy (dst, m_bytes.c_str(), len);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000297 m_bytes.erase(m_bytes.begin(), m_bytes.begin() + len);
298
299 return len;
300 }
301 return 0;
302}
303
304void
Caroline Ticeefed6132010-11-19 20:47:54 +0000305Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast, ConnectionStatus status)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000306{
307 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
Daniel Malead01b2952012-11-29 21:49:15 +0000308 "%p Communication::AppendBytesToCache (src = %p, src_len = %" PRIu64 ", broadcast = %i)",
Greg Clayton43e0af02012-09-18 18:04:04 +0000309 this, bytes, (uint64_t)len, broadcast);
Caroline Tice9fd58502011-02-03 20:02:43 +0000310 if ((bytes == NULL || len == 0)
311 && (status != lldb::eConnectionStatusEndOfFile))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000312 return;
313 if (m_callback)
314 {
315 // If the user registered a callback, then call it and do not broadcast
316 m_callback (m_callback_baton, bytes, len);
317 }
Greg Clayton756f8ae2011-08-19 23:28:37 +0000318 else if (bytes != NULL && len > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000319 {
320 Mutex::Locker locker(m_bytes_mutex);
321 m_bytes.append ((const char *)bytes, len);
322 if (broadcast)
323 BroadcastEventIfUnique (eBroadcastBitReadThreadGotBytes);
324 }
325}
326
327size_t
Greg Clayton73bf5db2011-06-17 01:22:15 +0000328Communication::ReadFromConnection (void *dst,
329 size_t dst_len,
330 uint32_t timeout_usec,
331 ConnectionStatus &status,
332 Error *error_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000334 lldb::ConnectionSP connection_sp (m_connection_sp);
335 if (connection_sp.get())
Greg Clayton73bf5db2011-06-17 01:22:15 +0000336 return connection_sp->Read (dst, dst_len, timeout_usec, status, error_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337 return 0;
338}
339
Caroline Tice82305fc2010-12-02 18:31:56 +0000340bool
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000341Communication::ReadThreadIsRunning ()
342{
Stephen Wilsona08cfb12011-01-12 04:22:54 +0000343 return m_read_thread_enabled;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000344}
345
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000346lldb::thread_result_t
347Communication::ReadThread (lldb::thread_arg_t p)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348{
349 Communication *comm = (Communication *)p;
350
Greg Clayton5160ce52013-03-27 23:08:40 +0000351 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMUNICATION));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000352
353 if (log)
354 log->Printf ("%p Communication::ReadThread () thread starting...", p);
355
356 uint8_t buf[1024];
357
358 Error error;
359 ConnectionStatus status = eConnectionStatusSuccess;
360 bool done = false;
361 while (!done && comm->m_read_thread_enabled)
362 {
Peter Collingbourneba23ca02011-06-18 23:52:14 +0000363 size_t bytes_read = comm->ReadFromConnection (buf, sizeof(buf), 5 * TimeValue::MicroSecPerSec, status, &error);
Greg Clayton73bf5db2011-06-17 01:22:15 +0000364 if (bytes_read > 0)
365 comm->AppendBytesToCache (buf, bytes_read, true, status);
366 else if ((bytes_read == 0)
367 && status == eConnectionStatusEndOfFile)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368 {
Greg Clayton73bf5db2011-06-17 01:22:15 +0000369 if (comm->GetCloseOnEOF ())
370 comm->Disconnect ();
371 comm->AppendBytesToCache (buf, bytes_read, true, status);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000372 }
373
374 switch (status)
375 {
376 case eConnectionStatusSuccess:
377 break;
378
Greg Clayton7788e5f2010-12-04 02:22:36 +0000379 case eConnectionStatusEndOfFile:
Caroline Tice9fd58502011-02-03 20:02:43 +0000380 if (comm->GetCloseOnEOF())
381 done = true;
382 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000383 case eConnectionStatusNoConnection: // No connection
384 case eConnectionStatusLostConnection: // Lost connection while connected to a valid connection
Greg Claytonf0066ad2014-05-02 00:45:31 +0000385 case eConnectionStatusInterrupted: // Interrupted
386
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000387 done = true;
388 // Fall through...
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000389 case eConnectionStatusError: // Check GetError() for details
390 case eConnectionStatusTimedOut: // Request timed out
Greg Clayton2d4edfb2010-11-06 01:53:30 +0000391 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +0000392 error.LogIfError (log,
393 "%p Communication::ReadFromConnection () => status = %s",
394 p,
395 Communication::ConnectionStatusAsCString (status));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000396 break;
397 }
398 }
Caroline Tice20ad3c42010-10-29 21:48:37 +0000399 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMUNICATION);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400 if (log)
401 log->Printf ("%p Communication::ReadThread () thread exiting...", p);
402
403 // Let clients know that this thread is exiting
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000404 comm->BroadcastEvent (eBroadcastBitReadThreadDidExit);
405 return NULL;
406}
407
408void
409Communication::SetReadThreadBytesReceivedCallback
410(
411 ReadThreadBytesReceived callback,
412 void *callback_baton
413)
414{
415 m_callback = callback;
416 m_callback_baton = callback_baton;
417}
418
419void
420Communication::SetConnection (Connection *connection)
421{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422 Disconnect (NULL);
Greg Clayton74d41932012-01-31 04:56:17 +0000423 StopReadThread(NULL);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000424 m_connection_sp.reset(connection);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000425}
Caroline Ticeceb6b132010-10-26 03:11:13 +0000426
427const char *
428Communication::ConnectionStatusAsCString (lldb::ConnectionStatus status)
429{
430 switch (status)
431 {
432 case eConnectionStatusSuccess: return "success";
433 case eConnectionStatusError: return "error";
434 case eConnectionStatusTimedOut: return "timed out";
435 case eConnectionStatusNoConnection: return "no connection";
436 case eConnectionStatusLostConnection: return "lost connection";
Greg Clayton7a5388b2011-03-20 04:57:14 +0000437 case eConnectionStatusEndOfFile: return "end of file";
Greg Claytonf0066ad2014-05-02 00:45:31 +0000438 case eConnectionStatusInterrupted: return "interrupted";
Caroline Ticeceb6b132010-10-26 03:11:13 +0000439 }
440
441 static char unknown_state_string[64];
442 snprintf(unknown_state_string, sizeof (unknown_state_string), "ConnectionStatus = %i", status);
443 return unknown_state_string;
444}