Ejemplo n.º 1
0
size_t
ModuleList::RemoveOrphans (bool mandatory)
{
    Mutex::Locker locker;
    
    if (mandatory)
    {
        locker.Lock (m_modules_mutex);
    }
    else
    {
        // Not mandatory, remove orphans if we can get the mutex
        if (!locker.TryLock(m_modules_mutex))
            return 0;
    }
    collection::iterator pos = m_modules.begin();
    size_t remove_count = 0;
    while (pos != m_modules.end())
    {
        if (pos->unique())
        {
            pos = RemoveImpl(pos);
            ++remove_count;
        }
        else
        {
            ++pos;
        }
    }
    return remove_count;
}
Ejemplo n.º 2
0
ConnectionStatus
ConnectionFileDescriptor::Disconnect (Error *error_ptr)
{
    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
    if (log)
        log->Printf ("%p ConnectionFileDescriptor::Disconnect ()",
                     static_cast<void*>(this));

    ConnectionStatus status = eConnectionStatusSuccess;

    if (!IsConnected())
    {
        if (log)
            log->Printf ("%p ConnectionFileDescriptor::Disconnect(): Nothing to disconnect",
                         static_cast<void*>(this));
        return eConnectionStatusSuccess;
    }

    if (m_read_sp && m_read_sp->IsValid() && m_read_sp->GetFdType() == IOObject::eFDTypeSocket)
        static_cast<Socket&>(*m_read_sp).PreDisconnect();

    // Try to get the ConnectionFileDescriptor's mutex.  If we fail, that is quite likely
    // because somebody is doing a blocking read on our file descriptor.  If that's the case,
    // then send the "q" char to the command file channel so the read will wake up and the connection
    // will then know to shut down.

    m_shutting_down = true;

    Mutex::Locker locker;
    bool got_lock = locker.TryLock (m_mutex);

    if (!got_lock)
    {
        if (m_pipe.WriteDescriptorIsValid())
        {
            int result;
            result = m_pipe.Write("q", 1) == 1;
            if (log)
                log->Printf ("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the lock, sent 'q' to %d, result = %d.",
                             static_cast<void*>(this), m_pipe.GetWriteFileDescriptor(), result);
        }
        else if (log)
        {
            log->Printf ("%p ConnectionFileDescriptor::Disconnect(): Couldn't get the lock, but no command pipe is available.",
                         static_cast<void*>(this));
        }
        locker.Lock (m_mutex);
    }

    Error error = m_read_sp->Close();
    Error error2 = m_write_sp->Close();
    if (error.Fail() || error2.Fail())
        status = eConnectionStatusError;
    if (error_ptr)
        *error_ptr = error.Fail() ? error : error2;

    m_shutting_down = false;
    return status;
}
bool
GDBRemoteCommunication::GetSequenceMutex (Mutex::Locker& locker, const char *failure_message)
{
    if (IsRunning())
        return locker.TryLock (m_sequence_mutex, failure_message);

    locker.Lock (m_sequence_mutex);
    return true;
}
Ejemplo n.º 4
0
size_t
ConnectionFileDescriptor::Read (void *dst, 
                                size_t dst_len, 
                                uint32_t timeout_usec,
                                ConnectionStatus &status, 
                                Error *error_ptr)
{
    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
    if (log)
        log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %llu)...",
                     this, m_fd_recv, dst, (uint64_t)dst_len);

    Mutex::Locker locker;
    bool got_lock = locker.TryLock (m_mutex);
    if (!got_lock)
    {
        if (log)
            log->Printf ("%p ConnectionFileDescriptor::Read () failed to get the connection lock.",
                     this);
        if (error_ptr)
            error_ptr->SetErrorString ("failed to get the connection lock for read.");
            
        status = eConnectionStatusTimedOut;
        return 0;
    }
    else if (m_shutting_down)
        return eConnectionStatusError;
    
    ssize_t bytes_read = 0;

    status = BytesAvailable (timeout_usec, error_ptr);
    if (status == eConnectionStatusSuccess)
    {
        do
        {
            bytes_read = ::read (m_fd_recv, dst, dst_len);
        } while (bytes_read < 0 && errno == EINTR);
    }

    if (status != eConnectionStatusSuccess)
        return 0;

    Error error;
    if (bytes_read == 0)
    {
        error.Clear(); // End-of-file.  Do not automatically close; pass along for the end-of-file handlers.
        status = eConnectionStatusEndOfFile;
    }
    else if (bytes_read < 0)
    {
        error.SetErrorToErrno();
    }
    else
    {
        error.Clear();
    }

    if (log)
        log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %llu) => %lli, error = %s",
                     this, 
                     m_fd_recv, 
                     dst, 
                     (uint64_t)dst_len,
                     (int64_t)bytes_read,
                     error.AsCString());

    if (error_ptr)
        *error_ptr = error;

    if (error.Fail())
    {
        uint32_t error_value = error.GetError();
        switch (error_value)
        {
        case EAGAIN:    // The file was marked for non-blocking I/O, and no data were ready to be read.
            if (m_fd_recv_type == eFDTypeSocket || m_fd_recv_type == eFDTypeSocketUDP)
                status = eConnectionStatusTimedOut;
            else
                status = eConnectionStatusSuccess;
            return 0;

        case EFAULT:    // Buf points outside the allocated address space.
        case EINTR:     // A read from a slow device was interrupted before any data arrived by the delivery of a signal.
        case EINVAL:    // The pointer associated with fildes was negative.
        case EIO:       // An I/O error occurred while reading from the file system.
                        // The process group is orphaned.
                        // The file is a regular file, nbyte is greater than 0,
                        // the starting position is before the end-of-file, and
                        // the starting position is greater than or equal to the
                        // offset maximum established for the open file
                        // descriptor associated with fildes.
        case EISDIR:    // An attempt is made to read a directory.
        case ENOBUFS:   // An attempt to allocate a memory buffer fails.
        case ENOMEM:    // Insufficient memory is available.
            status = eConnectionStatusError;
            break;  // Break to close....

        case ENOENT:    // no such file or directory
        case EBADF:     // fildes is not a valid file or socket descriptor open for reading.
        case ENXIO:     // An action is requested of a device that does not exist..
                        // A requested action cannot be performed by the device.
        case ECONNRESET:// The connection is closed by the peer during a read attempt on a socket.
        case ENOTCONN:  // A read is attempted on an unconnected socket.
            status = eConnectionStatusLostConnection;
            break;  // Break to close....

        case ETIMEDOUT: // A transmission timeout occurs during a read attempt on a socket.
            status = eConnectionStatusTimedOut;
            return 0;
        }

        //Disconnect (NULL);
        return 0;
    }
    return bytes_read;
}
Ejemplo n.º 5
0
ConnectionStatus
ConnectionFileDescriptor::Disconnect (Error *error_ptr)
{
    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
    if (log)
        log->Printf ("%p ConnectionFileDescriptor::Disconnect ()", this);

    ConnectionStatus status = eConnectionStatusSuccess;

    if (m_fd_send < 0 && m_fd_recv < 0)
    {
        if (log)
            log->Printf ("%p ConnectionFileDescriptor::Disconnect(): Nothing to disconnect", this);
        return eConnectionStatusSuccess;
    }
    
    // Try to get the ConnectionFileDescriptor's mutex.  If we fail, that is quite likely
    // because somebody is doing a blocking read on our file descriptor.  If that's the case,
    // then send the "q" char to the command file channel so the read will wake up and the connection
    // will then know to shut down.
    
    m_shutting_down = true;
    
    Mutex::Locker locker;
    bool got_lock= locker.TryLock (m_mutex);
    
    if (!got_lock)
    {
        if (m_pipe_write != -1 )
        {
            write (m_pipe_write, "q", 1);
            close (m_pipe_write);
            m_pipe_write = -1;
        }
        locker.Lock (m_mutex);
    }
    
    if (m_should_close_fd == true)
    {
        if (m_fd_send == m_fd_recv)
        {
            status = Close (m_fd_send, error_ptr);
        }
        else
        {
            // File descriptors are the different, close both if needed
            if (m_fd_send >= 0)
                status = Close (m_fd_send, error_ptr);
            if (m_fd_recv >= 0)
            {
                ConnectionStatus recv_status = Close (m_fd_recv, error_ptr);
                if (status == eConnectionStatusSuccess)
                    status = recv_status;
            }
        }
    }

    // Now set all our descriptors to invalid values.
    
    m_fd_send = m_fd_recv = -1;

    if (status != eConnectionStatusSuccess)
    {
        
        return status;
    }
        
    m_shutting_down = false;
    return eConnectionStatusSuccess;
}
Ejemplo n.º 6
0
bool
CommunicationKDP::GetSequenceMutex (Mutex::Locker& locker)
{
    return locker.TryLock (m_sequence_mutex);
}