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