<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>