ipc/unixfd/UnixFdWatcher.cpp

Wed, 31 Dec 2014 06:55:46 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:46 +0100
changeset 1
ca08bd8f51b2
permissions
-rw-r--r--

Added tag TORBROWSER_REPLICA for changeset 6474c204b198

michael@0 1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
michael@0 2 /* vim: set ts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include <fcntl.h>
michael@0 8 #include "UnixFdWatcher.h"
michael@0 9
michael@0 10 #ifdef CHROMIUM_LOG
michael@0 11 #undef CHROMIUM_LOG
michael@0 12 #endif
michael@0 13
michael@0 14 #if defined(MOZ_WIDGET_GONK)
michael@0 15 #include <android/log.h>
michael@0 16 #define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "I/O", args);
michael@0 17 #else
michael@0 18 #include <stdio.h>
michael@0 19 #define IODEBUG true
michael@0 20 #define CHROMIUM_LOG(args...) if (IODEBUG) printf(args);
michael@0 21 #endif
michael@0 22
michael@0 23 namespace mozilla {
michael@0 24 namespace ipc {
michael@0 25
michael@0 26 UnixFdWatcher::~UnixFdWatcher()
michael@0 27 {
michael@0 28 NS_WARN_IF(IsOpen()); /* mFd should have been closed already */
michael@0 29 }
michael@0 30
michael@0 31 void
michael@0 32 UnixFdWatcher::Close()
michael@0 33 {
michael@0 34 MOZ_ASSERT(MessageLoopForIO::current() == mIOLoop);
michael@0 35
michael@0 36 if (NS_WARN_IF(!IsOpen())) {
michael@0 37 /* mFd should have been open */
michael@0 38 return;
michael@0 39 }
michael@0 40 OnClose();
michael@0 41 RemoveWatchers(READ_WATCHER|WRITE_WATCHER);
michael@0 42 mFd.dispose();
michael@0 43 }
michael@0 44
michael@0 45 void
michael@0 46 UnixFdWatcher::AddWatchers(unsigned long aWatchers, bool aPersistent)
michael@0 47 {
michael@0 48 MOZ_ASSERT(MessageLoopForIO::current() == mIOLoop);
michael@0 49 MOZ_ASSERT(IsOpen());
michael@0 50
michael@0 51 // Before we add a watcher, we need to remove it! Removing is always
michael@0 52 // safe, but adding the same watcher twice can lead to endless loops
michael@0 53 // inside libevent.
michael@0 54 RemoveWatchers(aWatchers);
michael@0 55
michael@0 56 if (aWatchers & READ_WATCHER) {
michael@0 57 MessageLoopForIO::current()->WatchFileDescriptor(
michael@0 58 mFd,
michael@0 59 aPersistent,
michael@0 60 MessageLoopForIO::WATCH_READ,
michael@0 61 &mReadWatcher,
michael@0 62 this);
michael@0 63 }
michael@0 64 if (aWatchers & WRITE_WATCHER) {
michael@0 65 MessageLoopForIO::current()->WatchFileDescriptor(
michael@0 66 mFd,
michael@0 67 aPersistent,
michael@0 68 MessageLoopForIO::WATCH_WRITE,
michael@0 69 &mWriteWatcher,
michael@0 70 this);
michael@0 71 }
michael@0 72 }
michael@0 73
michael@0 74 void
michael@0 75 UnixFdWatcher::RemoveWatchers(unsigned long aWatchers)
michael@0 76 {
michael@0 77 MOZ_ASSERT(MessageLoopForIO::current() == mIOLoop);
michael@0 78 MOZ_ASSERT(IsOpen());
michael@0 79
michael@0 80 if (aWatchers & READ_WATCHER) {
michael@0 81 mReadWatcher.StopWatchingFileDescriptor();
michael@0 82 }
michael@0 83 if (aWatchers & WRITE_WATCHER) {
michael@0 84 mWriteWatcher.StopWatchingFileDescriptor();
michael@0 85 }
michael@0 86 }
michael@0 87
michael@0 88 void
michael@0 89 UnixFdWatcher::OnError(const char* aFunction, int aErrno)
michael@0 90 {
michael@0 91 MOZ_ASSERT(MessageLoopForIO::current() == mIOLoop);
michael@0 92
michael@0 93 CHROMIUM_LOG("%s failed with error %d (%s)",
michael@0 94 aFunction, aErrno, strerror(aErrno));
michael@0 95 }
michael@0 96
michael@0 97 UnixFdWatcher::UnixFdWatcher(MessageLoop* aIOLoop)
michael@0 98 : mIOLoop(aIOLoop)
michael@0 99 {
michael@0 100 MOZ_ASSERT(mIOLoop);
michael@0 101 }
michael@0 102
michael@0 103 UnixFdWatcher::UnixFdWatcher(MessageLoop* aIOLoop, int aFd)
michael@0 104 : mIOLoop(aIOLoop)
michael@0 105 , mFd(aFd)
michael@0 106 {
michael@0 107 MOZ_ASSERT(mIOLoop);
michael@0 108 }
michael@0 109
michael@0 110 void
michael@0 111 UnixFdWatcher::SetFd(int aFd)
michael@0 112 {
michael@0 113 MOZ_ASSERT(MessageLoopForIO::current() == mIOLoop);
michael@0 114 MOZ_ASSERT(!IsOpen());
michael@0 115 MOZ_ASSERT(FdIsNonBlocking(aFd));
michael@0 116
michael@0 117 mFd = aFd;
michael@0 118 }
michael@0 119
michael@0 120 bool
michael@0 121 UnixFdWatcher::FdIsNonBlocking(int aFd)
michael@0 122 {
michael@0 123 int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL));
michael@0 124 return (flags > 0) && (flags & O_NONBLOCK);
michael@0 125 }
michael@0 126
michael@0 127 }
michael@0 128 }

mercurial