1 //===-- Communication.cpp ---------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 // Other libraries and framework 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"
20 #include "lldb/Host/Host.h"
24 using namespace lldb_private;
27 Communication::GetStaticBroadcasterClass ()
29 static ConstString class_name ("lldb.communication");
33 //----------------------------------------------------------------------
35 //----------------------------------------------------------------------
36 Communication::Communication(const char *name) :
37 Broadcaster (NULL, name),
39 m_read_thread (LLDB_INVALID_HOST_THREAD),
40 m_read_thread_enabled (false),
42 m_bytes_mutex (Mutex::eMutexTypeRecursive),
43 m_write_mutex (Mutex::eMutexTypeNormal),
45 m_callback_baton (NULL),
49 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
50 "%p Communication::Communication (name = %s)",
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");
62 //----------------------------------------------------------------------
64 //----------------------------------------------------------------------
65 Communication::~Communication()
67 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
68 "%p Communication::~Communication (name = %s)",
69 this, m_broadcaster_name.AsCString(""));
74 Communication::Clear()
76 SetReadThreadBytesReceivedCallback (NULL, NULL);
78 StopReadThread (NULL);
82 Communication::Connect (const char *url, Error *error_ptr)
86 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Connect (url = %s)", this, url);
88 lldb::ConnectionSP connection_sp (m_connection_sp);
89 if (connection_sp.get())
90 return connection_sp->Connect (url, error_ptr);
92 error_ptr->SetErrorString("Invalid connection.");
93 return eConnectionStatusNoConnection;
97 Communication::Disconnect (Error *error_ptr)
99 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Disconnect ()", this);
101 lldb::ConnectionSP connection_sp (m_connection_sp);
102 if (connection_sp.get())
104 ConnectionStatus status = connection_sp->Disconnect (error_ptr);
105 // We currently don't protect connection_sp with any mutex for
106 // 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.
111 // This unique pointer will cleanup after itself when this object goes away,
112 // so there is no need to currently have it destroy itself immediately
114 //connection_sp.reset();
117 return eConnectionStatusNoConnection;
121 Communication::IsConnected () const
123 lldb::ConnectionSP connection_sp (m_connection_sp);
124 if (connection_sp.get())
125 return connection_sp->IsConnected ();
130 Communication::HasConnection () const
132 return m_connection_sp.get() != NULL;
136 Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, ConnectionStatus &status, Error *error_ptr)
138 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
139 "%p Communication::Read (dst = %p, dst_len = %" PRIu64 ", timeout = %u usec) connection = %p",
144 m_connection_sp.get());
146 if (m_read_thread_enabled)
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)
152 status = eConnectionStatusSuccess;
156 if (m_connection_sp.get() == NULL)
159 error_ptr->SetErrorString("Invalid connection.");
160 status = eConnectionStatusNoConnection;
163 // Set the timeout appropriately
164 TimeValue timeout_time;
165 if (timeout_usec != UINT32_MAX)
167 timeout_time = TimeValue::Now();
168 timeout_time.OffsetWithMicroSeconds (timeout_usec);
171 Listener listener ("Communication::Read");
172 listener.StartListeningForEvents (this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit);
174 while (listener.WaitForEvent (timeout_time.IsValid() ? &timeout_time : NULL, event_sp))
176 const uint32_t event_type = event_sp->GetType();
177 if (event_type & eBroadcastBitReadThreadGotBytes)
179 return GetCachedBytes (dst, dst_len);
182 if (event_type & eBroadcastBitReadThreadDidExit)
191 // We aren't using a read thread, just read the data synchronously in this
193 lldb::ConnectionSP connection_sp (m_connection_sp);
194 if (connection_sp.get())
196 return connection_sp->Read (dst, dst_len, timeout_usec, status, error_ptr);
200 error_ptr->SetErrorString("Invalid connection.");
201 status = eConnectionStatusNoConnection;
207 Communication::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr)
209 lldb::ConnectionSP connection_sp (m_connection_sp);
211 Mutex::Locker locker(m_write_mutex);
212 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
213 "%p Communication::Write (src = %p, src_len = %" PRIu64 ") connection = %p",
217 connection_sp.get());
219 if (connection_sp.get())
220 return connection_sp->Write (src, src_len, status, error_ptr);
223 error_ptr->SetErrorString("Invalid connection.");
224 status = eConnectionStatusNoConnection;
230 Communication::StartReadThread (Error *error_ptr)
235 if (IS_VALID_LLDB_HOST_THREAD(m_read_thread))
238 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
239 "%p Communication::StartReadThread ()", this);
242 char thread_name[1024];
243 snprintf(thread_name, sizeof(thread_name), "<lldb.comm.%s>", m_broadcaster_name.AsCString());
245 m_read_thread_enabled = true;
246 m_read_thread = Host::ThreadCreate (thread_name, Communication::ReadThread, this, error_ptr);
247 if (!IS_VALID_LLDB_HOST_THREAD(m_read_thread))
248 m_read_thread_enabled = false;
249 return m_read_thread_enabled;
253 Communication::StopReadThread (Error *error_ptr)
255 if (!IS_VALID_LLDB_HOST_THREAD(m_read_thread))
258 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
259 "%p Communication::StopReadThread ()", this);
261 m_read_thread_enabled = false;
263 BroadcastEvent (eBroadcastBitReadThreadShouldExit, NULL);
265 //Host::ThreadCancel (m_read_thread, error_ptr);
267 bool status = Host::ThreadJoin (m_read_thread, NULL, error_ptr);
268 m_read_thread = LLDB_INVALID_HOST_THREAD;
273 Communication::JoinReadThread (Error *error_ptr)
275 if (!IS_VALID_LLDB_HOST_THREAD(m_read_thread))
278 bool success = Host::ThreadJoin (m_read_thread, NULL, error_ptr);
279 m_read_thread = LLDB_INVALID_HOST_THREAD;
284 Communication::GetCachedBytes (void *dst, size_t dst_len)
286 Mutex::Locker locker(m_bytes_mutex);
287 if (m_bytes.size() > 0)
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
292 return m_bytes.size();
294 const size_t len = std::min<size_t>(dst_len, m_bytes.size());
296 ::memcpy (dst, m_bytes.c_str(), len);
297 m_bytes.erase(m_bytes.begin(), m_bytes.begin() + len);
305 Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast, ConnectionStatus status)
307 lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
308 "%p Communication::AppendBytesToCache (src = %p, src_len = %" PRIu64 ", broadcast = %i)",
309 this, bytes, (uint64_t)len, broadcast);
310 if ((bytes == NULL || len == 0)
311 && (status != lldb::eConnectionStatusEndOfFile))
315 // If the user registered a callback, then call it and do not broadcast
316 m_callback (m_callback_baton, bytes, len);
318 else if (bytes != NULL && len > 0)
320 Mutex::Locker locker(m_bytes_mutex);
321 m_bytes.append ((const char *)bytes, len);
323 BroadcastEventIfUnique (eBroadcastBitReadThreadGotBytes);
328 Communication::ReadFromConnection (void *dst,
330 uint32_t timeout_usec,
331 ConnectionStatus &status,
334 lldb::ConnectionSP connection_sp (m_connection_sp);
335 if (connection_sp.get())
336 return connection_sp->Read (dst, dst_len, timeout_usec, status, error_ptr);
341 Communication::ReadThreadIsRunning ()
343 return m_read_thread_enabled;
346 lldb::thread_result_t
347 Communication::ReadThread (lldb::thread_arg_t p)
349 Communication *comm = (Communication *)p;
351 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMUNICATION));
354 log->Printf ("%p Communication::ReadThread () thread starting...", p);
359 ConnectionStatus status = eConnectionStatusSuccess;
361 while (!done && comm->m_read_thread_enabled)
363 size_t bytes_read = comm->ReadFromConnection (buf, sizeof(buf), 5 * TimeValue::MicroSecPerSec, status, &error);
365 comm->AppendBytesToCache (buf, bytes_read, true, status);
366 else if ((bytes_read == 0)
367 && status == eConnectionStatusEndOfFile)
369 if (comm->GetCloseOnEOF ())
371 comm->AppendBytesToCache (buf, bytes_read, true, status);
376 case eConnectionStatusSuccess:
379 case eConnectionStatusEndOfFile:
380 if (comm->GetCloseOnEOF())
383 case eConnectionStatusNoConnection: // No connection
384 case eConnectionStatusLostConnection: // Lost connection while connected to a valid connection
387 case eConnectionStatusError: // Check GetError() for details
388 case eConnectionStatusTimedOut: // Request timed out
390 error.LogIfError (log,
391 "%p Communication::ReadFromConnection () => status = %s",
393 Communication::ConnectionStatusAsCString (status));
397 log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMUNICATION);
399 log->Printf ("%p Communication::ReadThread () thread exiting...", p);
401 // Let clients know that this thread is exiting
402 comm->BroadcastEvent (eBroadcastBitReadThreadDidExit);
407 Communication::SetReadThreadBytesReceivedCallback
409 ReadThreadBytesReceived callback,
413 m_callback = callback;
414 m_callback_baton = callback_baton;
418 Communication::SetConnection (Connection *connection)
421 StopReadThread(NULL);
422 m_connection_sp.reset(connection);
426 Communication::ConnectionStatusAsCString (lldb::ConnectionStatus status)
430 case eConnectionStatusSuccess: return "success";
431 case eConnectionStatusError: return "error";
432 case eConnectionStatusTimedOut: return "timed out";
433 case eConnectionStatusNoConnection: return "no connection";
434 case eConnectionStatusLostConnection: return "lost connection";
435 case eConnectionStatusEndOfFile: return "end of file";
438 static char unknown_state_string[64];
439 snprintf(unknown_state_string, sizeof (unknown_state_string), "ConnectionStatus = %i", status);
440 return unknown_state_string;