<div dir="ltr">Looks fine, thanks for the fix.</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Oct 22, 2014 at 9:30 AM, Abid, Hafiz <span dir="ltr"><<a href="mailto:Hafiz_Abid@mentor.com" target="_blank">Hafiz_Abid@mentor.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Zachary,<br>
Some 'goto' jumps over local variable with initialization in ConnectionGenericFileWindows.cpp.<br>
I think this makes the code ill-formed as per C++ standard 6.7.3. I have attached a simple<br>
fix for it. Please let me know if you see a problem with it. Otherwise I will apply it later today.<br>
<br>
Thanks,<br>
Abid<br>
<div><div class="h5"><br>
> -----Original Message-----<br>
> From: <a href="mailto:lldb-commits-bounces@cs.uiuc.edu">lldb-commits-bounces@cs.uiuc.edu</a> [mailto:<a href="mailto:lldb-commits-">lldb-commits-</a><br>
> <a href="mailto:bounces@cs.uiuc.edu">bounces@cs.uiuc.edu</a>] On Behalf Of Zachary Turner<br>
> Sent: 06 October 2014 22:23<br>
> To: <a href="mailto:lldb-commits@cs.uiuc.edu">lldb-commits@cs.uiuc.edu</a><br>
> Subject: [Lldb-commits] [lldb] r219145 - Create a ConnectionGenericFile class<br>
> for Windows.<br>
><br>
> Author: zturner<br>
> Date: Mon Oct 6 16:23:09 2014<br>
> New Revision: 219145<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=219145&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=219145&view=rev</a><br>
> Log:<br>
> Create a ConnectionGenericFile class for Windows.<br>
><br>
> This is the first step in getting ConnectionFileDescriptor ported to Windows.<br>
> It implements a connection against a disk file for windows. This supports<br>
> connection strings of the form file://PATH which are currently supported<br>
> only on posix platforms in ConnectionFileDescriptor.<br>
><br>
> Reviewed by: Greg Clayton<br>
> Differential Revision: <a href="http://reviews.llvm.org/D5608" target="_blank">http://reviews.llvm.org/D5608</a><br>
><br>
> Added:<br>
> lldb/trunk/include/lldb/Host/windows/ConnectionGenericFileWindows.h<br>
> lldb/trunk/source/Host/windows/ConnectionGenericFileWindows.cpp<br>
> Modified:<br>
> lldb/trunk/include/lldb/Core/Connection.h<br>
> lldb/trunk/include/lldb/lldb-types.h<br>
> lldb/trunk/source/API/SBCommunication.cpp<br>
> lldb/trunk/source/Core/Connection.cpp<br>
> lldb/trunk/source/Host/CMakeLists.txt<br>
><br>
> Modified: lldb/trunk/include/lldb/Core/Connection.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/lldb/trunk/include/lldb/Core/Connection.h?rev=219145&r1=219144<br>
> &r2=219145&view=diff<br>
> ================================================================<br>
> ==============<br>
> --- lldb/trunk/include/lldb/Core/Connection.h (original)<br>
> +++ lldb/trunk/include/lldb/Core/Connection.h Mon Oct 6 16:23:09 2014<br>
> @@ -46,6 +46,8 @@ public:<br>
> virtual<br>
> ~Connection ();<br>
><br>
> + static Connection *CreateDefaultConnection(const char *url);<br>
> +<br>
> //------------------------------------------------------------------<br>
> /// Connect using the connect string \a url.<br>
> ///<br>
><br>
> Added:<br>
> lldb/trunk/include/lldb/Host/windows/ConnectionGenericFileWindows.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/lldb/trunk/include/lldb/Host/windows/ConnectionGenericFileWindo<br>
> ws.h?rev=219145&view=auto<br>
> ================================================================<br>
> ==============<br>
> --- lldb/trunk/include/lldb/Host/windows/ConnectionGenericFileWindows.h<br>
> (added)<br>
> +++<br>
> lldb/trunk/include/lldb/Host/windows/ConnectionGenericFileWindows.h<br>
</div></div>> +++ Mon Oct 6 16:23:09 2014<br>
<span class="">> @@ -0,0 +1,64 @@<br>
> +//===-- ConnectionGenericFileWindows.h --------------------------*- C++<br>
</span>> +-*-===// //<br>
<span class="">> +// The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open<br>
</span>> +Source // License. See LICENSE.TXT for details.<br>
<span class="">> +//<br>
> +//===------------------------------------------------------------------<br>
> +----===//<br>
> +<br>
> +#ifndef liblldb_Host_windows_ConnectionGenericFileWindows_h_<br>
> +#define liblldb_Host_windows_ConnectionGenericFileWindows_h_<br>
> +<br>
> +#include "lldb/Core/Connection.h"<br>
> +#include "lldb/Host/windows/windows.h"<br>
> +#include "lldb/lldb-types.h"<br>
> +<br>
> +namespace lldb_private<br>
> +{<br>
> +<br>
> +class Error;<br>
> +<br>
> +class ConnectionGenericFile : public lldb_private::Connection {<br>
</span><div><div class="h5">> + public:<br>
> + ConnectionGenericFile();<br>
> +<br>
> + ConnectionGenericFile(lldb::file_t file, bool owns_file);<br>
> +<br>
> + virtual ~ConnectionGenericFile();<br>
> +<br>
> + virtual bool IsConnected() const;<br>
> +<br>
> + virtual lldb::ConnectionStatus Connect(const char *s, Error<br>
> + *error_ptr);<br>
> +<br>
> + virtual lldb::ConnectionStatus Disconnect(Error *error_ptr);<br>
> +<br>
> + virtual size_t Read(void *dst, size_t dst_len, uint32_t<br>
> + timeout_usec, lldb::ConnectionStatus &status, Error *error_ptr);<br>
> +<br>
> + virtual size_t Write(const void *src, size_t src_len,<br>
> + lldb::ConnectionStatus &status, Error *error_ptr);<br>
> +<br>
> + bool InterruptRead();<br>
> +<br>
> + protected:<br>
> + OVERLAPPED m_overlapped;<br>
> + HANDLE m_file;<br>
> + HANDLE m_event_handles[2];<br>
> + bool m_owns_file;<br>
> + LARGE_INTEGER m_file_position;<br>
> +<br>
> + enum<br>
> + {<br>
> + kBytesAvailableEvent,<br>
> + kInterruptEvent<br>
> + };<br>
> +<br>
> + private:<br>
> + void InitializeEventHandles();<br>
> + void IncrementFilePointer(DWORD amount);<br>
> +<br>
> + DISALLOW_COPY_AND_ASSIGN(ConnectionGenericFile);<br>
> +};<br>
> +}<br>
> +<br>
> +#endif<br>
><br>
> Modified: lldb/trunk/include/lldb/lldb-types.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-" target="_blank">http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-</a><br>
> types.h?rev=219145&r1=219144&r2=219145&view=diff<br>
> ================================================================<br>
> ==============<br>
> --- lldb/trunk/include/lldb/lldb-types.h (original)<br>
> +++ lldb/trunk/include/lldb/lldb-types.h Mon Oct 6 16:23:09 2014<br>
> @@ -51,6 +51,9 @@ namespace lldb<br>
> typedef void* rwlock_t;<br>
> typedef void* process_t; // Process type is HANDLE<br>
> typedef void* thread_t; // Host thread type<br>
> + typedef void* file_t; // Host file type<br>
> + typedef void* pipe_t; // Host pipe type<br>
> + typedef unsigned int __w64 socket_t; // Host socket type<br>
> typedef uint32_t thread_key_t;<br>
> typedef void* thread_arg_t; // Host thread argument<br>
> type<br>
> typedef unsigned thread_result_t; // Host thread result type<br>
> @@ -71,6 +74,9 @@ namespace lldb<br>
> typedef pthread_rwlock_t rwlock_t;<br>
> typedef uint64_t process_t; // Process type is just a pid.<br>
> typedef pthread_t thread_t; // Host thread type<br>
> + typedef int file_t; // Host file type<br>
> + typedef int pipe_t; // Host pipe type<br>
> + typedef int socket_t; // Host socket type<br>
> typedef pthread_key_t thread_key_t;<br>
> typedef void * thread_arg_t; // Host thread argument<br>
> type<br>
> typedef void * thread_result_t; // Host thread result type<br>
><br>
> Modified: lldb/trunk/source/API/SBCommunication.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/lldb/trunk/source/API/SBCommunication.cpp?rev=219145&r1=21914<br>
> 4&r2=219145&view=diff<br>
> ================================================================<br>
> ==============<br>
> --- lldb/trunk/source/API/SBCommunication.cpp (original)<br>
> +++ lldb/trunk/source/API/SBCommunication.cpp Mon Oct 6 16:23:09 2014<br>
> @@ -71,7 +71,7 @@ SBCommunication::Connect (const char *ur<br>
> if (m_opaque)<br>
> {<br>
> if (!m_opaque->HasConnection ())<br>
> - m_opaque->SetConnection (new ConnectionFileDescriptor());<br>
> +<br>
> + m_opaque->SetConnection(Connection::CreateDefaultConnection(url));<br>
> return m_opaque->Connect (url, NULL);<br>
> }<br>
> return eConnectionStatusNoConnection;<br>
><br>
> Modified: lldb/trunk/source/Core/Connection.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/lldb/trunk/source/Core/Connection.cpp?rev=219145&r1=219144&r2<br>
> =219145&view=diff<br>
> ================================================================<br>
> ==============<br>
> --- lldb/trunk/source/Core/Connection.cpp (original)<br>
> +++ lldb/trunk/source/Core/Connection.cpp Mon Oct 6 16:23:09 2014<br>
> @@ -13,6 +13,12 @@<br>
> // Project includes<br>
> #include "lldb/Core/Connection.h"<br>
><br>
> +#if defined(_WIN32)<br>
> +#include "lldb/Host/windows/ConnectionGenericFileWindows.h"<br>
> +#endif<br>
> +<br>
> +#include "lldb/Host/ConnectionFileDescriptor.h"<br>
> +<br>
> using namespace lldb_private;<br>
><br>
> Connection::Connection ()<br>
> @@ -22,3 +28,13 @@ Connection::Connection () Connection::~Connection ()<br>
> { }<br>
> +<br>
> +Connection *<br>
</div></div>> +Connection::CreateDefaultConnection(const char *url) { #if<br>
> +defined(_WIN32)<br>
<span class="">> + if (strstr(url, "file://") == url)<br>
</span>> + return new ConnectionGenericFile(); #endif<br>
> + return new ConnectionFileDescriptor(); }<br>
><br>
> Modified: lldb/trunk/source/Host/CMakeLists.txt<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/lldb/trunk/source/Host/CMakeLists.txt?rev=219145&r1=219144&r2=<br>
> 219145&view=diff<br>
> ================================================================<br>
<span class="">> ==============<br>
> --- lldb/trunk/source/Host/CMakeLists.txt (original)<br>
> +++ lldb/trunk/source/Host/CMakeLists.txt Mon Oct 6 16:23:09 2014<br>
> @@ -40,6 +40,7 @@ add_host_subdirectory(posix if<br>
> (CMAKE_SYSTEM_NAME MATCHES "Windows")<br>
> add_host_subdirectory(windows<br>
> windows/Condition.cpp<br>
> + windows/ConnectionGenericFileWindows.cpp<br>
> windows/EditLineWin.cpp<br>
> windows/FileSystem.cpp<br>
> windows/Host.cpp<br>
><br>
> Added:<br>
> lldb/trunk/source/Host/windows/ConnectionGenericFileWindows.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/lldb/trunk/source/Host/windows/ConnectionGenericFileWindows.cp<br>
> p?rev=219145&view=auto<br>
> ================================================================<br>
> ==============<br>
> --- lldb/trunk/source/Host/windows/ConnectionGenericFileWindows.cpp<br>
> (added)<br>
> +++ lldb/trunk/source/Host/windows/ConnectionGenericFileWindows.cpp<br>
> Mon<br>
</span>> +++ Oct 6 16:23:09 2014<br>
<span class="">> @@ -0,0 +1,337 @@<br>
> +//===-- ConnectionGenericFileWindows.cpp ------------------------*- C++<br>
</span>> +-*-===// //<br>
<span class="">> +// The LLVM Compiler Infrastructure<br>
> +//<br>
> +// This file is distributed under the University of Illinois Open<br>
</span>> +Source // License. See LICENSE.TXT for details.<br>
> +//<br>
> +//===------------------------------------------------------------------<br>
<span class="">> +----===//<br>
> +<br>
> +#include "lldb/Core/Error.h"<br>
> +#include "lldb/Core/Log.h"<br>
> +#include "lldb/Host/TimeValue.h"<br>
> +#include "lldb/Host/windows/ConnectionGenericFileWindows.h"<br>
> +<br>
> +#include "llvm/ADT/STLExtras.h"<br>
> +#include "llvm/ADT/StringRef.h"<br>
> +<br>
> +using namespace lldb;<br>
> +using namespace lldb_private;<br>
> +<br>
> +namespace<br>
> +{<br>
> +// This is a simple helper class to package up the information needed<br>
</span>> +to return from a Read/Write // operation function. Since there is alot<br>
> +of code to be run before exit regardless of whether the // operation<br>
> +succeeded or failed, combined with many possible return paths, this is the<br>
> cleanest // way to represent it.<br>
<div><div class="h5">> +class ReturnInfo<br>
> +{<br>
> + public:<br>
> + void<br>
> + Set(size_t bytes, ConnectionStatus status, DWORD error_code)<br>
> + {<br>
> + m_error.SetError(error_code, eErrorTypeWin32);<br>
> + m_bytes = bytes;<br>
> + m_status = status;<br>
> + }<br>
> +<br>
> + void<br>
> + Set(size_t bytes, ConnectionStatus status, llvm::StringRef error_msg)<br>
> + {<br>
> + m_error.SetErrorString(error_msg.data());<br>
> + m_bytes = bytes;<br>
> + m_status = status;<br>
> + }<br>
> +<br>
> + size_t<br>
> + GetBytes() const<br>
> + {<br>
> + return m_bytes;<br>
> + }<br>
> + ConnectionStatus<br>
> + GetStatus() const<br>
> + {<br>
> + return m_status;<br>
> + }<br>
> + const Error &<br>
> + GetError() const<br>
> + {<br>
> + return m_error;<br>
> + }<br>
> +<br>
> + private:<br>
> + Error m_error;<br>
> + size_t m_bytes;<br>
> + ConnectionStatus m_status;<br>
> +};<br>
> +}<br>
> +<br>
> +ConnectionGenericFile::ConnectionGenericFile()<br>
> + : m_file(INVALID_HANDLE_VALUE)<br>
> + , m_owns_file(false)<br>
> +{<br>
> + ::ZeroMemory(&m_overlapped, sizeof(m_overlapped));<br>
> + ::ZeroMemory(&m_file_position, sizeof(m_file_position));<br>
> + InitializeEventHandles();<br>
> +}<br>
> +<br>
> +ConnectionGenericFile::ConnectionGenericFile(lldb::file_t file, bool<br>
> owns_file)<br>
> + : m_file(file)<br>
> + , m_owns_file(owns_file)<br>
> +{<br>
> + ::ZeroMemory(&m_overlapped, sizeof(m_overlapped));<br>
> + ::ZeroMemory(&m_file_position, sizeof(m_file_position));<br>
> + InitializeEventHandles();<br>
> +}<br>
> +<br>
> +ConnectionGenericFile::~ConnectionGenericFile()<br>
> +{<br>
> + if (m_owns_file && IsConnected())<br>
> + ::CloseHandle(m_file);<br>
> +<br>
> + ::CloseHandle(m_event_handles[kBytesAvailableEvent]);<br>
> + ::CloseHandle(m_event_handles[kInterruptEvent]);<br>
> +}<br>
> +<br>
> +void<br>
> +ConnectionGenericFile::InitializeEventHandles()<br>
> +{<br>
> + m_event_handles[kInterruptEvent] = CreateEvent(NULL, FALSE, FALSE,<br>
</div></div>> +NULL);<br>
<span class="">> +<br>
> + // Note, we should use a manual reset event for the hEvent argument of<br>
> the OVERLAPPED. This<br>
> + // is because both WaitForMultipleObjects and GetOverlappedResult (if<br>
> you set the bWait<br>
> + // argument to TRUE) will wait for the event to be signalled. If we use an<br>
> auto-reset event,<br>
> + // WaitForMultipleObjects will reset the event, return successfully, and<br>
> then<br>
> + // GetOverlappedResult will block since the event is no longer signalled.<br>
> + m_event_handles[kBytesAvailableEvent] = ::CreateEvent(NULL, TRUE,<br>
</span>> +FALSE, NULL); }<br>
<span class="">> +<br>
> +bool<br>
> +ConnectionGenericFile::IsConnected() const {<br>
</span><span class="">> + return m_file && (m_file != INVALID_HANDLE_VALUE); }<br>
> +<br>
</span><span class="">> +lldb::ConnectionStatus<br>
> +ConnectionGenericFile::Connect(const char *s, Error *error_ptr) {<br>
</span><span class="">> + Log<br>
> *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));<br>
> + if (log)<br>
> + log->Printf("%p ConnectionGenericFile::Connect (url = '%s')",<br>
</span>> +static_cast<void *>(this), s);<br>
<div><div class="h5">> +<br>
> + if (strstr(s, "file://") != s)<br>
> + {<br>
> + if (error_ptr)<br>
> + error_ptr->SetErrorStringWithFormat("unsupported connection URL:<br>
> '%s'", s);<br>
> + return eConnectionStatusError;<br>
> + }<br>
> +<br>
> + if (IsConnected())<br>
> + {<br>
> + ConnectionStatus status = Disconnect(error_ptr);<br>
> + if (status != eConnectionStatusSuccess)<br>
> + return status;<br>
> + }<br>
> +<br>
> + // file://PATH<br>
> + const char *path = s + strlen("file://");<br>
> + // Open the file for overlapped access. If it does not exist, create it. We<br>
> open it overlapped<br>
> + // so that we can issue asynchronous reads and then use<br>
> WaitForMultipleObjects to allow the read<br>
> + // to be interrupted by an event object.<br>
> + m_file = ::CreateFile(path, GENERIC_READ | GENERIC_WRITE,<br>
> FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);<br>
> + if (m_file == INVALID_HANDLE_VALUE)<br>
> + {<br>
> + if (error_ptr)<br>
> + error_ptr->SetError(::GetLastError(), eErrorTypeWin32);<br>
> + return eConnectionStatusError;<br>
> + }<br>
> +<br>
> + m_owns_file = true;<br>
> + return eConnectionStatusSuccess;<br>
> +}<br>
> +<br>
> +lldb::ConnectionStatus<br>
> +ConnectionGenericFile::Disconnect(Error *error_ptr) {<br>
</div></div><span class="">> + Log<br>
> *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));<br>
> + if (log)<br>
> + log->Printf("%p ConnectionGenericFile::Disconnect (url =<br>
</span>> +'%s')", static_cast<void *>(this), s);<br>
<div><div class="h5">> +<br>
> + if (!IsConnected())<br>
> + return eConnectionStatusSuccess;<br>
> +<br>
> + // Reset the handle so that after we unblock any pending reads,<br>
> subsequent calls to Read() will<br>
> + // see a disconnected state.<br>
> + HANDLE old_file = m_file;<br>
> + m_file = INVALID_HANDLE_VALUE;<br>
> +<br>
> + // Set the disconnect event so that any blocking reads unblock, then<br>
> cancel any pending IO operations.<br>
> + ::CancelIoEx(old_file, &m_overlapped);<br>
> +<br>
> + // Close the file handle if we owned it, but don't close the event handles.<br>
> We could always<br>
> + // reconnect with the same Connection instance.<br>
> + if (m_owns_file)<br>
> + ::CloseHandle(old_file);<br>
> +<br>
> + ::ZeroMemory(&m_file_position, sizeof(m_file_position));<br>
> + m_owns_file = false;<br>
> + return eConnectionStatusSuccess;<br>
> +}<br>
> +<br>
> +size_t<br>
> +ConnectionGenericFile::Read(void *dst, size_t dst_len, uint32_t<br>
</div></div>> +timeout_usec, lldb::ConnectionStatus &status, Error *error_ptr) {<br>
<div><div class="h5">> + ReturnInfo return_info;<br>
> +<br>
> + if (error_ptr)<br>
> + error_ptr->Clear();<br>
> +<br>
> + if (!IsConnected())<br>
> + {<br>
> + return_info.Set(0, eConnectionStatusNoConnection,<br>
> ERROR_INVALID_HANDLE);<br>
> + goto finish;<br>
> + }<br>
> +<br>
> + m_overlapped.hEvent = m_event_handles[kBytesAvailableEvent];<br>
> +<br>
> + BOOL result = ::ReadFile(m_file, dst, dst_len, NULL, &m_overlapped);<br>
> + if (result || ::GetLastError() == ERROR_IO_PENDING)<br>
> + {<br>
> + if (!result)<br>
> + {<br>
> + // The expected return path. The operation is pending. Wait for<br>
> the operation to complete<br>
> + // or be interrupted.<br>
> + TimeValue time_value;<br>
> + time_value.OffsetWithMicroSeconds(timeout_usec);<br>
> + DWORD milliseconds = time_value.milliseconds();<br>
> + result =<br>
> ::WaitForMultipleObjects(llvm::array_lengthof(m_event_handles),<br>
> m_event_handles, FALSE, milliseconds);<br>
> + // All of the events are manual reset events, so make sure we reset<br>
> them to non-signalled.<br>
> + switch (result)<br>
> + {<br>
> + case WAIT_OBJECT_0 + kBytesAvailableEvent:<br>
> + break;<br>
> + case WAIT_OBJECT_0 + kInterruptEvent:<br>
> + return_info.Set(0, eConnectionStatusInterrupted, 0);<br>
> + goto finish;<br>
> + case WAIT_TIMEOUT:<br>
> + return_info.Set(0, eConnectionStatusTimedOut, 0);<br>
> + goto finish;<br>
> + case WAIT_FAILED:<br>
> + return_info.Set(0, eConnectionStatusError, ::GetLastError());<br>
> + goto finish;<br>
> + }<br>
> + }<br>
> + // The data is ready. Figure out how much was read and return;<br>
> + DWORD bytes_read = 0;<br>
> + if (!::GetOverlappedResult(m_file, &m_overlapped, &bytes_read,<br>
> FALSE))<br>
> + {<br>
> + DWORD result_error = ::GetLastError();<br>
> + // ERROR_OPERATION_ABORTED occurs when someone calls<br>
> Disconnect() during a blocking read.<br>
> + // This triggers a call to CancelIoEx, which causes the operation to<br>
> complete and the<br>
> + // result to be ERROR_OPERATION_ABORTED.<br>
> + if (result_error == ERROR_HANDLE_EOF || result_error ==<br>
> ERROR_OPERATION_ABORTED)<br>
> + return_info.Set(bytes_read, eConnectionStatusEndOfFile, 0);<br>
> + else<br>
> + return_info.Set(bytes_read, eConnectionStatusError,<br>
> result_error);<br>
> + }<br>
> + else if (bytes_read == 0)<br>
> + return_info.Set(bytes_read, eConnectionStatusEndOfFile, 0);<br>
> + else<br>
> + return_info.Set(bytes_read, eConnectionStatusSuccess, 0);<br>
> +<br>
> + goto finish;<br>
> + }<br>
> +<br>
> + // An unknown error occured. Fail out.<br>
> + return_info.Set(0, eConnectionStatusError, ::GetLastError());<br>
> + goto finish;<br>
> +<br>
> +finish:<br>
> + status = return_info.GetStatus();<br>
> + if (error_ptr)<br>
> + *error_ptr = return_info.GetError();<br>
> +<br>
> + // kBytesAvailableEvent is a manual reset event. Make sure it gets reset<br>
> here so that any<br>
> + // subsequent operations don't immediately see bytes available.<br>
> + ResetEvent(m_event_handles[kBytesAvailableEvent]);<br>
> +<br>
> + IncrementFilePointer(return_info.GetBytes());<br>
> + Log<br>
> *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));<br>
> + if (log)<br>
> + {<br>
> + log->Printf("%" PRIxPTR " ConnectionGenericFile::Read() handle = %"<br>
> PRIxPTR ", dst = %" PRIxPTR ", dst_len = %" PRIu64<br>
> + ") => %" PRIu64 ", error = %s",<br>
> + this, m_file, dst, static_cast<uint64_t>(dst_len),<br>
> static_cast<uint64_t>(return_info.GetBytes()),<br>
> + return_info.GetError().AsCString());<br>
> + }<br>
> +<br>
> + return return_info.GetBytes();<br>
> +}<br>
> +<br>
> +size_t<br>
> +ConnectionGenericFile::Write(const void *src, size_t src_len,<br>
</div></div>> +lldb::ConnectionStatus &status, Error *error_ptr) {<br>
<div class="HOEnZb"><div class="h5">> + ReturnInfo return_info;<br>
> +<br>
> + if (error_ptr)<br>
> + error_ptr->Clear();<br>
> +<br>
> + if (!IsConnected())<br>
> + {<br>
> + return_info.Set(0, eConnectionStatusNoConnection,<br>
> ERROR_INVALID_HANDLE);<br>
> + goto finish;<br>
> + }<br>
> +<br>
> + m_overlapped.hEvent = NULL;<br>
> +<br>
> + // Writes are not interruptible like reads are, so just block until it's done.<br>
> + BOOL result = ::WriteFile(m_file, src, src_len, NULL, &m_overlapped);<br>
> + if (!result && ::GetLastError() != ERROR_IO_PENDING)<br>
> + {<br>
> + return_info.Set(0, eConnectionStatusError, ::GetLastError());<br>
> + goto finish;<br>
> + }<br>
> +<br>
> + DWORD bytes_written = 0;<br>
> + if (!::GetOverlappedResult(m_file, &m_overlapped, &bytes_written,<br>
> TRUE))<br>
> + {<br>
> + return_info.Set(bytes_written, eConnectionStatusError,<br>
> ::GetLastError());<br>
> + goto finish;<br>
> + }<br>
> +<br>
> + return_info.Set(bytes_written, eConnectionStatusSuccess, 0);<br>
> + goto finish;<br>
> +<br>
> +finish:<br>
> + status = return_info.GetStatus();<br>
> + if (error_ptr)<br>
> + *error_ptr = return_info.GetError();<br>
> +<br>
> + IncrementFilePointer(return_info.GetBytes());<br>
> + Log<br>
> *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));<br>
> + if (log)<br>
> + {<br>
> + log->Printf("%" PRIxPTR " ConnectionGenericFile::Write() handle = %"<br>
> PRIxPTR ", src = %" PRIxPTR ", src_len = %" PRIu64<br>
> + ") => %" PRIu64 ", error = %s",<br>
> + this, m_file, src, static_cast<uint64_t>(src_len),<br>
> static_cast<uint64_t>(return_info.GetBytes()),<br>
> + return_info.GetError().AsCString());<br>
> + }<br>
> + return return_info.GetBytes();<br>
> +}<br>
> +<br>
> +bool<br>
> +ConnectionGenericFile::InterruptRead()<br>
> +{<br>
> + return ::SetEvent(m_event_handles[kInterruptEvent]);<br>
> +}<br>
> +<br>
> +void<br>
> +ConnectionGenericFile::IncrementFilePointer(DWORD amount) {<br>
</div></div><span class="im HOEnZb">> + LARGE_INTEGER old_pos;<br>
> + old_pos.HighPart = m_overlapped.OffsetHigh;<br>
> + old_pos.LowPart = m_overlapped.Offset;<br>
> + old_pos.QuadPart += amount;<br>
> + m_overlapped.Offset = old_pos.LowPart;<br>
> + m_overlapped.OffsetHigh = old_pos.HighPart; }<br>
</span><div class="HOEnZb"><div class="h5">> \ No newline at end of file<br>
><br>
><br>
> _______________________________________________<br>
> lldb-commits mailing list<br>
> <a href="mailto:lldb-commits@cs.uiuc.edu">lldb-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits</a><br>
</div></div></blockquote></div><br></div>