gecko/ipc/unixfd/UnixFdWatcher.cpp
Thomas Zimmermann 51ec78121a Bug 974410: Added watcher classes for Unix file descriptors, r=kyle
These new classes encasulate file-descriptor watchers, basic file
descriptors, and socket connections. Each class contains callback
methods for it's implemented functionality. Users should inherit
from the classes and overload the callback with their own code.
2014-02-26 17:51:52 +01:00

120 lines
2.6 KiB
C++

/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "UnixFdWatcher.h"
#ifdef CHROMIUM_LOG
#undef CHROMIUM_LOG
#endif
#if defined(MOZ_WIDGET_GONK)
#include <android/log.h>
#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "I/O", args);
#else
#include <stdio.h>
#define IODEBUG true
#define CHROMIUM_LOG(args...) if (IODEBUG) printf(args);
#endif
namespace mozilla {
namespace ipc {
UnixFdWatcher::~UnixFdWatcher()
{
NS_WARN_IF(IsOpen()); /* mFd should have been closed already */
}
void
UnixFdWatcher::Close()
{
MOZ_ASSERT(MessageLoopForIO::current() == mIOLoop);
if (NS_WARN_IF(!IsOpen())) {
/* mFd should have been open */
return;
}
OnClose();
RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
mFd.dispose();
}
void
UnixFdWatcher::AddWatchers(unsigned long aWatchers, bool aPersistent)
{
MOZ_ASSERT(MessageLoopForIO::current() == mIOLoop);
MOZ_ASSERT(IsOpen());
// Before we add a watcher, we need to remove it! Removing is always
// safe, but adding the same watcher twice can lead to endless loops
// inside libevent.
RemoveWatchers(aWatchers);
if (aWatchers & READ_WATCHER) {
MessageLoopForIO::current()->WatchFileDescriptor(
mFd,
aPersistent,
MessageLoopForIO::WATCH_READ,
&mReadWatcher,
this);
}
if (aWatchers & WRITE_WATCHER) {
MessageLoopForIO::current()->WatchFileDescriptor(
mFd,
aPersistent,
MessageLoopForIO::WATCH_WRITE,
&mWriteWatcher,
this);
}
}
void
UnixFdWatcher::RemoveWatchers(unsigned long aWatchers)
{
MOZ_ASSERT(MessageLoopForIO::current() == mIOLoop);
MOZ_ASSERT(IsOpen());
if (aWatchers & READ_WATCHER) {
mReadWatcher.StopWatchingFileDescriptor();
}
if (aWatchers & WRITE_WATCHER) {
mWriteWatcher.StopWatchingFileDescriptor();
}
}
void
UnixFdWatcher::OnError(const char* aFunction, int aErrno)
{
MOZ_ASSERT(MessageLoopForIO::current() == mIOLoop);
CHROMIUM_LOG("%s failed with error %d (%s)",
aFunction, aErrno, strerror(aErrno));
}
UnixFdWatcher::UnixFdWatcher(MessageLoop* aIOLoop)
: mIOLoop(aIOLoop)
{
MOZ_ASSERT(mIOLoop);
}
UnixFdWatcher::UnixFdWatcher(MessageLoop* aIOLoop, int aFd)
: mIOLoop(aIOLoop)
, mFd(aFd)
{
MOZ_ASSERT(mIOLoop);
}
void
UnixFdWatcher::SetFd(int aFd)
{
MOZ_ASSERT(MessageLoopForIO::current() == mIOLoop);
MOZ_ASSERT(!IsOpen());
mFd = aFd;
}
}
}