blob: 0a82a3e4876eb53a485a701d579c6f18cdca17e8 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "mojo/edk/base_edk/platform_handle_watcher_impl.h"
#include "base/logging.h"
#include "base/macros.h"
#include "mojo/edk/util/make_unique.h"
using mojo::platform::PlatformHandle;
using mojo::platform::PlatformHandleWatcher;
using mojo::util::MakeUnique;
namespace base_edk {
namespace {
class WatchTokenImpl : public PlatformHandleWatcher::WatchToken,
public base::MessageLoopForIO::Watcher {
public:
WatchTokenImpl(std::function<void()>&& read_callback,
std::function<void()>&& write_callback)
: read_callback_(std::move(read_callback)),
write_callback_(std::move(write_callback)) {}
~WatchTokenImpl() override {}
base::MessageLoopForIO::FileDescriptorWatcher* base_fd_watcher() {
return &base_fd_watcher_;
}
private:
// |base::MessageLoopForIO::Watcher| implementation:
void OnFileCanReadWithoutBlocking(int /*fd*/) override {
DCHECK(read_callback_);
read_callback_();
}
void OnFileCanWriteWithoutBlocking(int /*fd*/) override {
DCHECK(write_callback_);
write_callback_();
}
const std::function<void()> read_callback_;
const std::function<void()> write_callback_;
base::MessageLoopForIO::FileDescriptorWatcher base_fd_watcher_;
DISALLOW_COPY_AND_ASSIGN(WatchTokenImpl);
};
} // namespace
PlatformHandleWatcherImpl::PlatformHandleWatcherImpl(
base::MessageLoopForIO* base_message_loop_for_io)
: base_message_loop_for_io_(base_message_loop_for_io) {}
PlatformHandleWatcherImpl::~PlatformHandleWatcherImpl() {}
std::unique_ptr<PlatformHandleWatcher::WatchToken>
PlatformHandleWatcherImpl::Watch(PlatformHandle platform_handle,
bool persistent,
std::function<void()>&& read_callback,
std::function<void()>&& write_callback) {
DCHECK(platform_handle.is_valid());
DCHECK(read_callback || write_callback);
base::MessageLoopForIO::Mode mode;
if (read_callback && write_callback) {
mode = base::MessageLoopForIO::WATCH_READ_WRITE;
} else if (read_callback) {
mode = base::MessageLoopForIO::WATCH_READ;
} else {
DCHECK(write_callback);
mode = base::MessageLoopForIO::WATCH_WRITE;
}
auto rv = MakeUnique<WatchTokenImpl>(std::move(read_callback),
std::move(write_callback));
CHECK(base_message_loop_for_io_->WatchFileDescriptor(
platform_handle.fd, persistent, mode, rv->base_fd_watcher(), rv.get()));
return std::move(rv);
}
} // namespace base_edk