I don't want to be snarky, but you guys who are interested in having WIndows libraries are slowly reproducing the work I already did and submitted as part of https://issues.apache.org/jira/browse/THRIFT-591.
This includes a full ASIO based implementation of local sockets, implemented as
Unix domain sockets on *nix, and Windows named pipes on Windows. It won't apply
against the current sources, but the named pipe stuff was all new code anyway.
- Rush
On Dec 2, 2011, at 10:47 AM, Alex Parenteau wrote:
> Hi Peace,
>
> I would use boost::asio, and use the ability of it to handle Windows/Posix
> file descriptors.
>
> Below are some snippets of code that might help illustrate this (don't try to
> compile!)
>
> I don't know much of the pipe transport in thrift, so this may not be
> applicable to your question.
>
> As an orthogonal thought, I was wondering if anybody has put some thought
> around using boost::asio for async thrift servers (right now using libevent).
>
> Regards,
> alex
>
> #include <boost/asio.hpp>
> #include <boost/system/windows_error.hpp>
>
> #ifdef DVA_OS_WIN
> using boost::asio::windows::stream_handle;
> typedef stream_handle platform_stream;
> typedef HANDLE platform_descriptor;
> # define PIPE_EOF_ERROR_CODE boost::system::windows_error::broken_pipe
> #else
> using boost::asio::posix::stream_descriptor;
> typedef stream_descriptor platform_stream;
> typedef int platform_descriptor;
> # define PIPE_EOF_ERROR_CODE boost::asio::error::eof
> #endif
>
> boost::asio::io_service io_service_;
> platform_stream pipe_;
> std::vector<char> data_;
> bool done_;
> bool error_;
> size_t total_size_;
> boost::asio::strand strand_;
> boost::thread thread_;
>
> PipeSession(platform_descriptor fd) :
> io_service_(), pipe_(io_service_, fd),
> {
> }
>
> bool PipeSession ::start()
> {
> #ifdef LINUX
> for (;;)
> {
> boost::asio::posix::descriptor_base::bytes_readable
> command(true);
> pipe_.io_control(command);
> std::size_t bytes_readable = command.get();
>
> if(bytes_readable) {
> break;
> }
> }
> #endif
> _thread = boost::thread(boost::bind(&PipeSession::run))
>
> return true;
> }
>
> void PipeSession ::run() {
> try {
> pipe_.async_read_some(boost::asio::buffer(data_),
> strand_.wrap(boost::bind(&PipeSession::handle_read,
> this, boost::asio::placeholders::error,
> boost::asio::placeholders::bytes_transferred)));
>
> std::size_t num = io_service_.run();
>
> } catch(const boost::system::system_error& e) {
> done_ = true;
> if(e.code() != PIPE_EOF_ERROR_CODE)
> throw;
> }
>
> static platform_descriptor CreatePipeFD(const std::string& pipeName,
> bool readFlag) {
> #ifdef WIN32
> HANDLE fd = CreateNamedPipe(
> pipeName.c_str(), // pipe name
> PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, //
> read/write access TODO PIPE_ACCESS_INBOUND? PIPE_ACCESS_OUTBOUND?
> PIPE_TYPE_BYTE | // byte type pipe
> PIPE_READMODE_BYTE | // byte-read mode
> PIPE_WAIT, // blocking mode
> PIPE_UNLIMITED_INSTANCES, // max. instances
> BUFSIZE, // output buffer size
> BUFSIZE, // input buffer size
> 0, // client time-out
> NULL); // default security attribute
>
> if(fd == INVALID_HANDLE_VALUE) {
> throw std::runtime_error("CreateNamedPipe failed");
> }
>
> OVERLAPPED overlapped = {0};
> overlapped.hEvent = CreateEvent(0,TRUE,FALSE,0);
> if(ConnectNamedPipe(fd, &overlapped) != FALSE || GetLastError()
> != ERROR_IO_PENDING) {
> CloseHandle(overlapped.hEvent);
> CloseHandle(fd);
> throw std::runtime_error("ConnectNamedPipe failed");
> }
> #else
> if(mkfifo(pipeName .c_str(), 0660) < 0) {
> throw std::runtime_error("fifo failed");
> }
>
> int fd = open(pipeName c_str(), (readFlag ? O_RDONLY : O_RDWR)
> | O_NONBLOCK);
> if(fd <= 0) {
> throw std::runtime_error("open failed");
> }
> #endif
>
> #ifdef WIN32
> DWORD waitRes;
> if((waitRes = WaitForSingleObject(overlapped.hEvent,
> LAUNCH_TIMEOUT * 1000)) != WAIT_OBJECT_0) {
> CloseHandle(overlapped.hEvent);
> CloseHandle(fd);
> throw std::runtime_error("WaitForSingleObject failed");
> }
> CloseHandle(overlapped.hEvent);
>
> #endif
>
> return fd;
> }
> }
>
> -----Original Message-----
> From: Peace [mailto:[email protected]]
> Sent: Thursday, December 01, 2011 3:24 PM
> To: [email protected]
> Subject: Pipe transport for Windows
>
> Hello group,
>
> I am implementing Named and Anonymous Pipes transport for Thrift on the
> Windows platform. The motivation for this is to provide a lightweight local
> IPC transport for applications that run entirely on one system. Unix already
> has domain sockets support in the TSocket transport but that does not work on
> Windows. I would have preferred a cross-platform solution but Windows pipes
> are much too different from the Unix implementations. What are your thoughts
> on submitting this for possible inclusion? Would a Windows-only transport
> bother people? Is there a better way to accomplish this?
>
>
> Regards,
> Peace
smime.p7s
Description: S/MIME cryptographic signature
