blob: fce764509d68f30a473d29c354225d71463db594 [file] [log] [blame]
/*!
* Copyright (c) 2017 by Contributors
* \file pipe.h
* \brief Platform independent pipe, used for IPC.
*/
#ifndef TVM_COMMON_PIPE_H_
#define TVM_COMMON_PIPE_H_
#include <dmlc/logging.h>
#include <dmlc/io.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#include <errno.h>
#include <cstring>
#include <cstdlib>
#endif
namespace tvm {
namespace common {
/*! \brief Platform independent pipe */
class Pipe : public dmlc::Stream {
public:
#ifdef _WIN32
using PipeHandle = HANDLE;
#else
using PipeHandle = int;
#endif
/*! \brief Construct a pipe from system handle. */
explicit Pipe(int64_t handle)
: handle_(static_cast<PipeHandle>(handle)) {}
/*! \brief destructor */
~Pipe() {
Flush();
}
using Stream::Read;
using Stream::Write;
/*!
* \brief reads data from a file descriptor
* \param ptr pointer to a memory buffer
* \param size block size
* \return the size of data read
*/
size_t Read(void *ptr, size_t size) final {
if (size == 0) return 0;
#ifdef _WIN32
DWORD nread;
CHECK(ReadFile(handle_, static_cast<TCHAR*>(ptr),
&nread, nullptr))
<< "Read Error: " << GetLastError();
#else
ssize_t nread;
nread = read(handle_, ptr, size);
CHECK_GE(nread, 0)
<< "Write Error: " << strerror(errno);
#endif
return static_cast<size_t>(nread);
}
/*!
* \brief write data to a file descriptor
* \param ptr pointer to a memory buffer
* \param size block size
* \return the size of data read
*/
void Write(const void *ptr, size_t size) final {
if (size == 0) return;
#ifdef _WIN32
DWORD nwrite;
CHECK(WriteFile(handle_, static_cast<const TCHAR*>(ptr),
&nwrite, nullptr) &&
static_cast<size_t>(nwrite) == size)
<< "Write Error: " << GetLastError();
#else
ssize_t nwrite;
nwrite = write(handle_, ptr, size);
CHECK_EQ(static_cast<size_t>(nwrite), size)
<< "Write Error: " << strerror(errno);
#endif
}
/*!
* \brief Flush the pipe;
*/
void Flush() {
#ifdef _WIN32
FlushFileBuffers(handle_);
#endif
}
/*! \brief close the pipe */
void Close() {
#ifdef _WIN32
CloseHandle(handle_);
#else
close(handle_);
#endif
}
private:
PipeHandle handle_;
};
} // namespace common
} // namespace tvm
#endif // TVM_COMMON_PIPE_H_