使用Boost :: asio posix stream_descriptor

时间:2016-07-12 13:47:02

标签: c++ linux-kernel boost-asio named-pipes ftrace

我正在尝试构建一个在调试时从ftrace pipes读取的应用程序。

尝试从 trace_pipe 或。异步读取时 trace_pipe_raw 使用boost :: asio API,正在管道中等待的事件正在进行中 通过async_read句柄处理并打印到屏幕,但是在程序启动后到达的新事件不会触发async_read句柄。

运行下面的示例代码,我打印了所有在队列中等待的活动,但我没有获得以后到达的新活动的打印件。

如果我尝试使用mkfifo从手动创建的管道读取但是不适用于ftrace管道,则相同的样本可以正常工作。

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <string>
#include <iostream>

namespace asio = boost::asio;
#ifdef BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR
typedef asio::posix::stream_descriptor stream_descriptor;
#endif

class PipeReader
{
    typedef std::shared_ptr<PipeReader> PipeReaderPtr;
    typedef std::weak_ptr<PipeReader> PipeReaderWeakPtr;
public:
    static PipeReaderWeakPtr Create(asio::io_service& io_service, const std::string& path);

    void HandleRead(PipeReaderPtr me, const boost::system::error_code &error);
private:
    PipeReader(asio::io_service& io_service, const std::string& path);
    stream_descriptor m_pipe;
    char buf[4096];
};

PipeReader::PipeReaderWeakPtr PipeReader::Create(asio::io_service& io_service, const std::string& path)
{
    PipeReaderPtr ptr(new PipeReader(io_service, path));

    ptr->m_pipe.async_read_some(boost::asio::buffer(ptr->buf),
                                boost::bind(&PipeReader::HandleRead,
                                            ptr.get(), 
                                            ptr,
                                            asio::placeholders::error));
    return ptr;
}

PipeReader::PipeReader(asio::io_service& io_service, const std::string& path)
                       : m_pipe(io_service)
{
    int dev = open(path.c_str(), O_RDWR);
    if (dev == -1) {
        std::cout << "failed to open path - " << path << std::endl;
    }
    else
    {
        m_pipe.assign(dev);
    }
}

void PipeReader::HandleRead(PipeReaderPtr me, const boost::system::error_code &error) 
{
    if (!error) {
        std::string str(me->buf);

        std::cout << "got message: " << str << std::endl;
        m_pipe.async_read_some(boost::asio::buffer(me->buf),
                               boost::bind(&PipeReader::HandleRead,
                                           this,
                                           me,
                                           asio::placeholders::error));
    }
    else
    {
        std::cout << "got error - " << error.message() << std::endl;
    }
}


int main()
{
    boost::asio::io_service io_service;
    boost::asio::io_service::work dummy(io_service);

    PipeReader::Create(io_service, "/sys/kernel/debug/tracing/trace_pipe");

    io_service.run();   
    return 0;
}

1 个答案:

答案 0 :(得分:1)

我发现了问题。这是一个导致epoll挂起的ftrace实现中的错误。 该错误已在内核3.16修复。

correspondence threadcommit in git hub