blob: ea84843fe0b3069fbeaffff28e065fdbe109336e [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"
Zachary Turner39de3112014-09-09 20:54:56 +000021#include "lldb/Host/HostThread.h"
22#include "lldb/Host/ThreadLauncher.h"
Eli Friedman88966972010-06-09 08:50:27 +000023#include <string.h>
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024
25using namespace lldb;
26using namespace lldb_private;
27
Jim Ingham4bddaeb2012-02-16 06:50:00 +000028ConstString &
29Communication::GetStaticBroadcasterClass ()
30{
31 static ConstString class_name ("lldb.communication");
32 return class_name;
33}
34
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035//----------------------------------------------------------------------
36// Constructor
37//----------------------------------------------------------------------
Greg Claytond46c87a2010-12-04 02:39:47 +000038Communication::Communication(const char *name) :
Jim Ingham4bddaeb2012-02-16 06:50:00 +000039 Broadcaster (NULL, name),
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000040 m_connection_sp (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041 m_read_thread_enabled (false),
42 m_bytes(),
43 m_bytes_mutex (Mutex::eMutexTypeRecursive),
Greg Clayton7ec3d402011-01-27 09:02:32 +000044 m_write_mutex (Mutex::eMutexTypeNormal),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045 m_callback (NULL),
Caroline Tice82305fc2010-12-02 18:31:56 +000046 m_callback_baton (NULL),
Greg Claytond46c87a2010-12-04 02:39:47 +000047 m_close_on_eof (true)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048
49{
50 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
51 "%p Communication::Communication (name = %s)",
52 this, name);
Greg Clayton95bf0fd2011-04-01 00:29:43 +000053
54 SetEventName (eBroadcastBitDisconnected, "disconnected");
55 SetEventName (eBroadcastBitReadThreadGotBytes, "got bytes");
56 SetEventName (eBroadcastBitReadThreadDidExit, "read thread did exit");
57 SetEventName (eBroadcastBitReadThreadShouldExit, "read thread should exit");
58 SetEventName (eBroadcastBitPacketAvailable, "packet available");
Jim Ingham4bddaeb2012-02-16 06:50:00 +000059
60 CheckInWithManager();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000061}
62
63//----------------------------------------------------------------------
64// Destructor
65//----------------------------------------------------------------------
66Communication::~Communication()
67{
68 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
69 "%p Communication::~Communication (name = %s)",
70 this, m_broadcaster_name.AsCString(""));
71 Clear();
72}
73
74void
75Communication::Clear()
76{
Greg Clayton756f8ae2011-08-19 23:28:37 +000077 SetReadThreadBytesReceivedCallback (NULL, NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000078 Disconnect (NULL);
Greg Clayton74d41932012-01-31 04:56:17 +000079 StopReadThread (NULL);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080}
81
82ConnectionStatus
Chris Lattner30fdc8d2010-06-08 16:52:24 +000083Communication::Connect (const char *url, Error *error_ptr)
84{
85 Clear();
86
87 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Connect (url = %s)", this, url);
88
Greg Clayton8b2fe6d2010-12-14 02:59:59 +000089 lldb::ConnectionSP connection_sp (m_connection_sp);
90 if (connection_sp.get())
91 return connection_sp->Connect (url, error_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000092 if (error_ptr)
93 error_ptr->SetErrorString("Invalid connection.");
94 return eConnectionStatusNoConnection;
95}
96
97ConnectionStatus
98Communication::Disconnect (Error *error_ptr)
99{
100 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Disconnect ()", this);
101
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000102 lldb::ConnectionSP connection_sp (m_connection_sp);
103 if (connection_sp.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000104 {
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000105 ConnectionStatus status = connection_sp->Disconnect (error_ptr);
106 // We currently don't protect connection_sp with any mutex for
Greg Claytonbfae66a2010-12-12 21:50:57 +0000107 // multi-threaded environments. So lets not nuke our connection class
108 // without putting some multi-threaded protections in. We also probably
109 // don't want to pay for the overhead it might cause if every time we
110 // access the connection we have to take a lock.
111 //
Greg Claytone01e07b2013-04-18 18:10:51 +0000112 // This unique pointer will cleanup after itself when this object goes away,
Greg Claytonbfae66a2010-12-12 21:50:57 +0000113 // so there is no need to currently have it destroy itself immediately
114 // upon disconnnect.
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000115 //connection_sp.reset();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000116 return status;
117 }
118 return eConnectionStatusNoConnection;
119}
120
121bool
122Communication::IsConnected () const
123{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000124 lldb::ConnectionSP connection_sp (m_connection_sp);
125 if (connection_sp.get())
126 return connection_sp->IsConnected ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000127 return false;
128}
129
130bool
131Communication::HasConnection () const
132{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000133 return m_connection_sp.get() != NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000134}
135
136size_t
137Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, ConnectionStatus &status, Error *error_ptr)
138{
139 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
Daniel Malead01b2952012-11-29 21:49:15 +0000140 "%p Communication::Read (dst = %p, dst_len = %" PRIu64 ", timeout = %u usec) connection = %p",
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000141 this,
142 dst,
Greg Clayton43e0af02012-09-18 18:04:04 +0000143 (uint64_t)dst_len,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000144 timeout_usec,
145 m_connection_sp.get());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146
Stephen Wilsona08cfb12011-01-12 04:22:54 +0000147 if (m_read_thread_enabled)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000148 {
149 // We have a dedicated read thread that is getting data for us
150 size_t cached_bytes = GetCachedBytes (dst, dst_len);
151 if (cached_bytes > 0 || timeout_usec == 0)
152 {
153 status = eConnectionStatusSuccess;
154 return cached_bytes;
155 }
156
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000157 if (m_connection_sp.get() == NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000158 {
159 if (error_ptr)
160 error_ptr->SetErrorString("Invalid connection.");
161 status = eConnectionStatusNoConnection;
162 return 0;
163 }
164 // Set the timeout appropriately
165 TimeValue timeout_time;
166 if (timeout_usec != UINT32_MAX)
167 {
168 timeout_time = TimeValue::Now();
169 timeout_time.OffsetWithMicroSeconds (timeout_usec);
170 }
171
172 Listener listener ("Communication::Read");
173 listener.StartListeningForEvents (this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit);
174 EventSP event_sp;
175 while (listener.WaitForEvent (timeout_time.IsValid() ? &timeout_time : NULL, event_sp))
176 {
177 const uint32_t event_type = event_sp->GetType();
178 if (event_type & eBroadcastBitReadThreadGotBytes)
179 {
180 return GetCachedBytes (dst, dst_len);
181 }
182
183 if (event_type & eBroadcastBitReadThreadDidExit)
184 {
185 Disconnect (NULL);
186 break;
187 }
188 }
189 return 0;
190 }
191
192 // We aren't using a read thread, just read the data synchronously in this
193 // thread.
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000194 lldb::ConnectionSP connection_sp (m_connection_sp);
195 if (connection_sp.get())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000196 {
Greg Clayton73bf5db2011-06-17 01:22:15 +0000197 return connection_sp->Read (dst, dst_len, timeout_usec, status, error_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000198 }
199
200 if (error_ptr)
201 error_ptr->SetErrorString("Invalid connection.");
202 status = eConnectionStatusNoConnection;
203 return 0;
204}
205
206
207size_t
208Communication::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr)
209{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000210 lldb::ConnectionSP connection_sp (m_connection_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000211
Jason Molendaccd41e52012-10-04 22:47:07 +0000212 Mutex::Locker locker(m_write_mutex);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000213 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
Daniel Malead01b2952012-11-29 21:49:15 +0000214 "%p Communication::Write (src = %p, src_len = %" PRIu64 ") connection = %p",
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000215 this,
216 src,
Greg Clayton43e0af02012-09-18 18:04:04 +0000217 (uint64_t)src_len,
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000218 connection_sp.get());
219
220 if (connection_sp.get())
221 return connection_sp->Write (src, src_len, status, error_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000222
223 if (error_ptr)
224 error_ptr->SetErrorString("Invalid connection.");
225 status = eConnectionStatusNoConnection;
226 return 0;
227}
228
229
230bool
231Communication::StartReadThread (Error *error_ptr)
232{
Greg Clayton1cb64962011-03-24 04:28:38 +0000233 if (error_ptr)
234 error_ptr->Clear();
235
Zachary Turneracee96a2014-09-23 18:32:09 +0000236 if (m_read_thread.IsJoinable())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000237 return true;
238
239 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
240 "%p Communication::StartReadThread ()", this);
241
242
243 char thread_name[1024];
244 snprintf(thread_name, sizeof(thread_name), "<lldb.comm.%s>", m_broadcaster_name.AsCString());
245
Greg Clayton86c3f342010-09-15 05:19:45 +0000246 m_read_thread_enabled = true;
Zachary Turner39de3112014-09-09 20:54:56 +0000247 m_read_thread = ThreadLauncher::LaunchThread(thread_name, Communication::ReadThread, this, error_ptr);
Zachary Turneracee96a2014-09-23 18:32:09 +0000248 if (!m_read_thread.IsJoinable())
Greg Clayton86c3f342010-09-15 05:19:45 +0000249 m_read_thread_enabled = false;
Greg Clayton26661bc2010-07-23 15:43:25 +0000250 return m_read_thread_enabled;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000251}
252
253bool
254Communication::StopReadThread (Error *error_ptr)
255{
Zachary Turneracee96a2014-09-23 18:32:09 +0000256 if (!m_read_thread.IsJoinable())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000257 return true;
258
259 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
260 "%p Communication::StopReadThread ()", this);
261
262 m_read_thread_enabled = false;
263
264 BroadcastEvent (eBroadcastBitReadThreadShouldExit, NULL);
265
Zachary Turner39de3112014-09-09 20:54:56 +0000266 // error = m_read_thread.Cancel();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000267
Zachary Turner39de3112014-09-09 20:54:56 +0000268 Error error = m_read_thread.Join(nullptr);
Zachary Turner39de3112014-09-09 20:54:56 +0000269 return error.Success();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000270}
271
Greg Clayton59042602014-01-30 18:52:57 +0000272bool
273Communication::JoinReadThread (Error *error_ptr)
274{
Zachary Turneracee96a2014-09-23 18:32:09 +0000275 if (!m_read_thread.IsJoinable())
Greg Clayton59042602014-01-30 18:52:57 +0000276 return true;
277
Zachary Turner39de3112014-09-09 20:54:56 +0000278 Error error = m_read_thread.Join(nullptr);
Zachary Turner39de3112014-09-09 20:54:56 +0000279 return error.Success();
Greg Clayton59042602014-01-30 18:52:57 +0000280}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000281
282size_t
283Communication::GetCachedBytes (void *dst, size_t dst_len)
284{
285 Mutex::Locker locker(m_bytes_mutex);
286 if (m_bytes.size() > 0)
287 {
288 // If DST is NULL and we have a thread, then return the number
289 // of bytes that are available so the caller can call again
290 if (dst == NULL)
291 return m_bytes.size();
292
293 const size_t len = std::min<size_t>(dst_len, m_bytes.size());
294
Greg Clayton471b31c2010-07-20 22:52:08 +0000295 ::memcpy (dst, m_bytes.c_str(), len);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000296 m_bytes.erase(m_bytes.begin(), m_bytes.begin() + len);
297
298 return len;
299 }
300 return 0;
301}
302
303void
Caroline Ticeefed6132010-11-19 20:47:54 +0000304Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast, ConnectionStatus status)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000305{
306 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
Daniel Malead01b2952012-11-29 21:49:15 +0000307 "%p Communication::AppendBytesToCache (src = %p, src_len = %" PRIu64 ", broadcast = %i)",
Greg Clayton43e0af02012-09-18 18:04:04 +0000308 this, bytes, (uint64_t)len, broadcast);
Caroline Tice9fd58502011-02-03 20:02:43 +0000309 if ((bytes == NULL || len == 0)
310 && (status != lldb::eConnectionStatusEndOfFile))
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000311 return;
312 if (m_callback)
313 {
314 // If the user registered a callback, then call it and do not broadcast
315 m_callback (m_callback_baton, bytes, len);
316 }
Greg Clayton756f8ae2011-08-19 23:28:37 +0000317 else if (bytes != NULL && len > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000318 {
319 Mutex::Locker locker(m_bytes_mutex);
320 m_bytes.append ((const char *)bytes, len);
321 if (broadcast)
322 BroadcastEventIfUnique (eBroadcastBitReadThreadGotBytes);
323 }
324}
325
326size_t
Greg Clayton73bf5db2011-06-17 01:22:15 +0000327Communication::ReadFromConnection (void *dst,
328 size_t dst_len,
329 uint32_t timeout_usec,
330 ConnectionStatus &status,
331 Error *error_ptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000332{
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000333 lldb::ConnectionSP connection_sp (m_connection_sp);
334 if (connection_sp.get())
Greg Clayton73bf5db2011-06-17 01:22:15 +0000335 return connection_sp->Read (dst, dst_len, timeout_usec, status, error_ptr);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000336 return 0;
337}
338
Caroline Tice82305fc2010-12-02 18:31:56 +0000339bool
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340Communication::ReadThreadIsRunning ()
341{
Stephen Wilsona08cfb12011-01-12 04:22:54 +0000342 return m_read_thread_enabled;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000343}
344
Virgile Bellob2f1fb22013-08-23 12:44:05 +0000345lldb::thread_result_t
346Communication::ReadThread (lldb::thread_arg_t p)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000347{
348 Communication *comm = (Communication *)p;
349
Greg Clayton5160ce52013-03-27 23:08:40 +0000350 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMUNICATION));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000351
352 if (log)
353 log->Printf ("%p Communication::ReadThread () thread starting...", p);
354
355 uint8_t buf[1024];
356
357 Error error;
358 ConnectionStatus status = eConnectionStatusSuccess;
359 bool done = false;
360 while (!done && comm->m_read_thread_enabled)
361 {
Peter Collingbourneba23ca02011-06-18 23:52:14 +0000362 size_t bytes_read = comm->ReadFromConnection (buf, sizeof(buf), 5 * TimeValue::MicroSecPerSec, status, &error);
Greg Clayton73bf5db2011-06-17 01:22:15 +0000363 if (bytes_read > 0)
364 comm->AppendBytesToCache (buf, bytes_read, true, status);
365 else if ((bytes_read == 0)
366 && status == eConnectionStatusEndOfFile)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000367 {
Greg Clayton73bf5db2011-06-17 01:22:15 +0000368 if (comm->GetCloseOnEOF ())
369 comm->Disconnect ();
370 comm->AppendBytesToCache (buf, bytes_read, true, status);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000371 }
372
373 switch (status)
374 {
375 case eConnectionStatusSuccess:
376 break;
377
Greg Clayton7788e5f2010-12-04 02:22:36 +0000378 case eConnectionStatusEndOfFile:
Caroline Tice9fd58502011-02-03 20:02:43 +0000379 if (comm->GetCloseOnEOF())
380 done = true;
381 break;
Todd Fiala42628282014-08-21 17:16:26 +0000382 case eConnectionStatusError: // Check GetError() for details
383 if (error.GetType() == eErrorTypePOSIX && error.GetError() == EIO)
384 {
385 // EIO on a pipe is usually caused by remote shutdown
386 comm->Disconnect ();
387 done = true;
388 }
389 if (log)
390 error.LogIfError (log,
391 "%p Communication::ReadFromConnection () => status = %s",
392 p,
393 Communication::ConnectionStatusAsCString (status));
394 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000395 case eConnectionStatusNoConnection: // No connection
396 case eConnectionStatusLostConnection: // Lost connection while connected to a valid connection
Greg Claytonf0066ad2014-05-02 00:45:31 +0000397 case eConnectionStatusInterrupted: // Interrupted
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000398 done = true;
399 // Fall through...
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400 case eConnectionStatusTimedOut: // Request timed out
Greg Clayton2d4edfb2010-11-06 01:53:30 +0000401 if (log)
Greg Clayton5160ce52013-03-27 23:08:40 +0000402 error.LogIfError (log,
403 "%p Communication::ReadFromConnection () => status = %s",
404 p,
405 Communication::ConnectionStatusAsCString (status));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000406 break;
407 }
408 }
Caroline Tice20ad3c42010-10-29 21:48:37 +0000409 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMUNICATION);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000410 if (log)
411 log->Printf ("%p Communication::ReadThread () thread exiting...", p);
412
413 // Let clients know that this thread is exiting
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000414 comm->BroadcastEvent (eBroadcastBitReadThreadDidExit);
415 return NULL;
416}
417
418void
419Communication::SetReadThreadBytesReceivedCallback
420(
421 ReadThreadBytesReceived callback,
422 void *callback_baton
423)
424{
425 m_callback = callback;
426 m_callback_baton = callback_baton;
427}
428
429void
430Communication::SetConnection (Connection *connection)
431{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000432 Disconnect (NULL);
Greg Clayton74d41932012-01-31 04:56:17 +0000433 StopReadThread(NULL);
Greg Clayton8b2fe6d2010-12-14 02:59:59 +0000434 m_connection_sp.reset(connection);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435}
Caroline Ticeceb6b132010-10-26 03:11:13 +0000436
437const char *
438Communication::ConnectionStatusAsCString (lldb::ConnectionStatus status)
439{
440 switch (status)
441 {
442 case eConnectionStatusSuccess: return "success";
443 case eConnectionStatusError: return "error";
444 case eConnectionStatusTimedOut: return "timed out";
445 case eConnectionStatusNoConnection: return "no connection";
446 case eConnectionStatusLostConnection: return "lost connection";
Greg Clayton7a5388b2011-03-20 04:57:14 +0000447 case eConnectionStatusEndOfFile: return "end of file";
Greg Claytonf0066ad2014-05-02 00:45:31 +0000448 case eConnectionStatusInterrupted: return "interrupted";
Caroline Ticeceb6b132010-10-26 03:11:13 +0000449 }
450
451 static char unknown_state_string[64];
452 snprintf(unknown_state_string, sizeof (unknown_state_string), "ConnectionStatus = %i", status);
453 return unknown_state_string;
454}