bool StartDBus() { MOZ_ASSERT(!NS_IsMainThread()); NS_ENSURE_TRUE(!gDBusConnection, true); RawDBusConnection* connection = new RawDBusConnection(); nsresult rv = connection->EstablishDBusConnection(); NS_ENSURE_SUCCESS(rv, false); XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new WatchDBusConnectionTask(connection)); gDBusConnection = connection; return true; }
void TestEndpointBridgeMainSubParent::ActorDestroy(ActorDestroyReason why) { if (NormalShutdown != why) { fail("unexpected destruction!"); } // ActorDestroy() is just a callback from IPDL-generated code, // which needs the top-level actor (this) to stay alive a little // longer so other things can be cleaned up. MessageLoop::current()->PostTask( FROM_HERE, new DeleteTask<TestEndpointBridgeMainSubParent>(this)); XRE_GetIOMessageLoop()->PostTask( FROM_HERE, new DeleteTask<Transport>(GetTransport())); }
void UnixSocketImpl::Connect() { if(mFd.get() < 0) { mFd = mConnector->Create(); if (mFd.get() < 0) { return; } } int ret; socklen_t addr_sz; struct sockaddr addr; mConnector->CreateAddr(false, addr_sz, &addr, mAddress.get()); ret = connect(mFd.get(), &addr, addr_sz); if (ret) { #if DEBUG LOG("Socket connect errno=%d\n", errno); #endif mFd.reset(-1); nsRefPtr<OnSocketEventTask> t = new OnSocketEventTask(this, OnSocketEventTask::CONNECT_ERROR); NS_DispatchToMainThread(t); return; } if (!mConnector->SetUp(mFd)) { NS_WARNING("Could not set up socket!"); return; } nsRefPtr<OnSocketEventTask> t = new OnSocketEventTask(this, OnSocketEventTask::CONNECT_SUCCESS); NS_DispatchToMainThread(t); // Due to the fact that we've dispatched our OnConnectSuccess message before // starting reading, we're guaranteed that any subsequent read tasks will // happen after the object has been notified of a successful connect. XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new StartImplReadingTask(this)); }
/*static*/ VRManagerChild* VRManagerChild::StartUpInChildProcess(Transport* aTransport, ProcessId aOtherPid) { MOZ_ASSERT(NS_IsMainThread()); // There's only one VRManager per child process. MOZ_ASSERT(!sVRManagerChildSingleton); RefPtr<VRManagerChild> child(new VRManagerChild()); if (!child->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(), ipc::ChildSide)) { NS_RUNTIMEABORT("Couldn't Open() Compositor channel."); return nullptr; } sVRManagerChildSingleton = child; return sVRManagerChildSingleton; }
bool UnixSocketConsumer::SendSocketData(const nsACString& aStr) { MOZ_ASSERT(NS_IsMainThread()); if (!mImpl) { return false; } if (aStr.Length() > MAX_READ_SIZE) { return false; } MOZ_ASSERT(!mImpl->IsShutdownOnMainThread()); UnixSocketRawData* d = new UnixSocketRawData(aStr.Length()); memcpy(d->mData, aStr.BeginReading(), aStr.Length()); XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new SocketSendTask(this, mImpl, d)); return true; }
bool UnixSocketConsumer::ConnectSocket(UnixSocketConnector* aConnector, const char* aAddress) { MOZ_ASSERT(aConnector); MOZ_ASSERT(NS_IsMainThread()); if (mImpl) { NS_WARNING("Socket already connecting/connected!"); return false; } nsCString addr; addr.Assign(aAddress); mImpl = new UnixSocketImpl(this, aConnector, addr); XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new SocketConnectTask(mImpl)); mConnectionStatus = SOCKET_CONNECTING; return true; }
//static void Volume::UpdateMountLock(const nsACString& aVolumeName, const int32_t& aMountGeneration, const bool& aMountLocked) { MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default); MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop()); RefPtr<Volume> vol = VolumeManager::FindVolumeByName(aVolumeName); if (!vol || (vol->mMountGeneration != aMountGeneration)) { return; } if (vol->mMountLocked != aMountLocked) { vol->mMountLocked = aMountLocked; DBG("Volume::UpdateMountLock for '%s' to %d\n", vol->NameStr(), (int)aMountLocked); mEventObserverList.Broadcast(vol); } }
static void ConnectImageBridgeInChildProcess(Transport* aTransport, ProcessId aOtherPid) { // Bind the IPC channel to the image bridge thread. sImageBridgeChildSingleton->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(), ipc::ChildSide); #ifdef MOZ_NUWA_PROCESS if (IsNuwaProcess()) { sImageBridgeChildThread ->message_loop()->PostTask(FROM_HERE, NewRunnableFunction(NuwaMarkCurrentThread, (void (*)(void *))nullptr, (void *)nullptr)); } #endif }
void nsVolume::UpdateMountLock(bool aMountLocked) { MOZ_ASSERT(XRE_IsParentProcess()); MOZ_ASSERT(NS_IsMainThread()); if (aMountLocked == mMountLocked) { return; } // The locked/unlocked state changed. Tell IOThread about it. mMountLocked = aMountLocked; LogState(); XRE_GetIOMessageLoop()->PostTask( FROM_HERE, NewRunnableFunction(Volume::UpdateMountLock, NS_LossyConvertUTF16toASCII(Name()), MountGeneration(), aMountLocked)); }
//static void Volume::RegisterVolumeObserver(Volume::EventObserver* aObserver, const char* aName) { MOZ_ASSERT(XRE_IsParentProcess()); MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop()); sEventObserverList.AddObserver(aObserver); DBG("Added Volume Observer '%s' @%p, length = %u", aName, aObserver, sEventObserverList.Length()); // Send an initial event to the observer (for each volume) size_t numVolumes = VolumeManager::NumVolumes(); for (size_t volIndex = 0; volIndex < numVolumes; volIndex++) { RefPtr<Volume> vol = VolumeManager::GetVolume(volIndex); aObserver->Notify(vol); } }
nsresult BluetoothDaemonConnection::ConnectSocket(BluetoothDaemonPDUConsumer* aConsumer) { MOZ_ASSERT(NS_IsMainThread()); if (mIO) { CHROMIUM_LOG("Bluetooth daemon already connecting/connected!"); return NS_ERROR_FAILURE; } SetConnectionStatus(SOCKET_CONNECTING); MessageLoop* ioLoop = XRE_GetIOMessageLoop(); mIO = new BluetoothDaemonConnectionIO( ioLoop, -1, UnixSocketWatcher::SOCKET_IS_CONNECTING, this, aConsumer); ioLoop->PostTask(FROM_HERE, new BluetoothDaemonConnectTask(mIO)); return NS_OK; }
void UnixSocketConsumer::CloseSocket() { // Needed due to refcount change MOZ_ASSERT(NS_IsMainThread()); if (!mImpl) { return; } UnixSocketImpl* impl = mImpl; // To make sure the owner doesn't die on the IOThread, remove pointer here mImpl = nullptr; // Line it up to be destructed on the IO Thread impl->mConsumer.forget(); impl->StopTask(); XRE_GetIOMessageLoop()->PostTask(FROM_HERE, NewRunnableFunction(DestroyImpl, impl)); NotifyDisconnect(); }
PTestBridgeMainSubChild* TestBridgeSubChild::AllocPTestBridgeMainSub(Transport* transport, ProcessId otherProcess) { ProcessHandle h; if (!base::OpenProcessHandle(otherProcess, &h)) { return nullptr; } nsAutoPtr<TestBridgeMainSubChild> a(new TestBridgeMainSubChild(transport)); if (!a->Open(transport, h, XRE_GetIOMessageLoop(), AsyncChannel::Child)) { return nullptr; } if (!a->SendHello()) fail("sending Hello"); return a.forget(); }
void UnixSocketConsumer::CloseSocket() { MOZ_ASSERT(NS_IsMainThread()); if (!mImpl) { return; } // From this point on, we consider mImpl as being deleted. // We sever the relationship here so any future calls to listen or connect // will create a new implementation. mImpl->ShutdownOnMainThread(); XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new ShutdownSocketTask(mImpl)); mImpl = nullptr; NotifyDisconnect(); }
PGMPContentParent* GMPServiceChild::AllocPGMPContentParent(Transport* aTransport, ProcessId aOtherPid) { MOZ_ASSERT(!mContentParents.GetWeak(aOtherPid)); nsCOMPtr<nsIThread> mainThread = do_GetMainThread(); MOZ_ASSERT(mainThread); nsRefPtr<GMPContentParent> parent = new GMPContentParent(); DebugOnly<bool> ok = parent->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(), mozilla::ipc::ParentSide); MOZ_ASSERT(ok); mContentParents.Put(aOtherPid, parent); return parent; }
void StopNetd() { MOZ_ASSERT(NS_IsMainThread()); nsIThread* currentThread = NS_GetCurrentThread(); NS_ASSERTION(currentThread, "This should never be null!"); XRE_GetIOMessageLoop()->PostTask( FROM_HERE, NewRunnableFunction(ShutdownNetdIOThread)); while (gNetdConsumer) { if (!NS_ProcessNextEvent(currentThread)) { NS_WARNING("Something bad happened!"); break; } } }
bool UnixSocketConsumer::ListenSocket(UnixSocketConnector* aConnector) { MOZ_ASSERT(aConnector); MOZ_ASSERT(NS_IsMainThread()); nsAutoPtr<UnixSocketConnector> connector(aConnector); if (mImpl) { NS_WARNING("Socket already connecting/connected!"); return false; } mImpl = new UnixSocketImpl(this, connector.forget(), EmptyCString()); mConnectionStatus = SOCKET_LISTENING; XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new SocketAcceptTask(mImpl)); return true; }
/*static*/ PCompositorParent* CompositorParent::Create(Transport* aTransport, ProcessId aOtherProcess) { nsRefPtr<CrossProcessCompositorParent> cpcp = new CrossProcessCompositorParent(aTransport, aOtherProcess); ProcessHandle handle; if (!base::OpenProcessHandle(aOtherProcess, &handle)) { // XXX need to kill |aOtherProcess|, it's boned return nullptr; } cpcp->mSelfRef = cpcp; CompositorLoop()->PostTask( FROM_HERE, NewRunnableFunction(OpenCompositor, cpcp.get(), aTransport, handle, XRE_GetIOMessageLoop())); // The return value is just compared to null for success checking, // we're not sharing a ref. return cpcp.get(); }
// static void NetdClient::SendNetdCommandIOThread(NetdCommand* aMessage) { MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop()); MOZ_ASSERT(aMessage); if (!gNetdClient) { LOG("Netd Client is not initialized"); return; } gNetdClient->mOutgoingQ.push(aMessage); if (gNetdClient->mSocket.get() == INVALID_SOCKET) { LOG("Netd connection is not established, push the message to queue"); return; } gNetdClient->WriteNetdCommand(); }
/*static*/ PCompositorChild* CompositorChild::Create(Transport* aTransport, ProcessId aOtherProcess) { // There's only one compositor per child process. MOZ_ASSERT(!sCompositor); nsRefPtr<CompositorChild> child(new CompositorChild(nullptr)); ProcessHandle handle; if (!base::OpenProcessHandle(aOtherProcess, &handle)) { // We can't go on without a compositor. NS_RUNTIMEABORT("Couldn't OpenProcessHandle() to parent process."); return nullptr; } if (!child->Open(aTransport, handle, XRE_GetIOMessageLoop(), ipc::ChildSide)) { NS_RUNTIMEABORT("Couldn't Open() Compositor channel."); return nullptr; } // We release this ref in ActorDestroy(). return sCompositor = child.forget().get(); }
void ListenSocket::Close() { MOZ_ASSERT(NS_IsMainThread()); if (!mIO) { return; } // From this point on, we consider mIO as being deleted. We sever // the relationship here so any future calls to listen or connect // will create a new implementation. mIO->ShutdownOnMainThread(); XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new SocketIOShutdownTask(mIO)); mIO = nullptr; NotifyDisconnect(); }
void NotifyDataArrived() { if (mOmxReader->IsShutdown()) { return; } while (mLength) { uint32_t length = std::min<uint64_t>(mLength, UINT32_MAX); mOmxReader->NotifyDataArrived(Interval<int64_t>(mOffset, mOffset + length)); mLength -= length; mOffset += length; } if (static_cast<uint64_t>(mOffset) < mFullLength) { // We cannot read data in the main thread because it // might block for too long. Instead we post an IO task // to the IO thread if there is more data available. XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new ProcessCachedDataTask(mOmxReader.get(), mOffset)); } }
void NotifyDataArrived() { const char* buffer = mBuffer.get(); while (mLength) { uint32_t length = std::min<uint64_t>(mLength, UINT32_MAX); mOmxReader->NotifyDataArrived(buffer, length, mOffset); buffer += length; mLength -= length; mOffset += length; } if (mOffset < mFullLength) { // We cannot read data in the main thread because it // might block for too long. Instead we post an IO task // to the IO thread if there is more data available. XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new OmxReaderProcessCachedDataTask(mOmxReader.get(), mOffset)); } }
bool ListenSocket::Listen(UnixSocketConnector* aConnector, ConnectionOrientedSocket* aCOSocket) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(aConnector); MOZ_ASSERT(aCOSocket); nsAutoPtr<UnixSocketConnector> connector(aConnector); if (mIO) { NS_WARNING("Socket already connecting/connected!"); return false; } mIO = new ListenSocketIO( XRE_GetIOMessageLoop(), this, connector.forget(), EmptyCString()); // Prepared I/O object, now start listening. return Listen(aCOSocket); }
static void MaybeInit() { MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop()); if (sShutdown || sMonitor) { // Don't init twice or init after shutdown. return; } sMonitor = new Monitor("ShutdownNetlinkPoller.monitor"); { ShutdownNetlinkPoller* shutdownPoller = new ShutdownNetlinkPoller(); nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction([=] () -> void { sShutdownPoller = shutdownPoller; ClearOnShutdown(&sShutdownPoller); // Must run on the main thread. }); MOZ_ASSERT(runnable); MOZ_ALWAYS_SUCCEEDS( NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL)); } }
void GonkDiskSpaceWatcher::DoStart() { NS_ASSERTION(XRE_GetIOMessageLoop() == MessageLoopForIO::current(), "Not on the correct message loop"); mFd = fanotify_init(FAN_CLASS_NOTIF, FAN_CLOEXEC | O_LARGEFILE); if (mFd == -1) { if (errno == ENOSYS) { // Don't change these printf_stderr since we need these logs even // in opt builds. printf_stderr("Warning: No fanotify support in this device's kernel.\n"); #if ANDROID_VERSION >= 19 MOZ_CRASH("Fanotify support must be enabled in the kernel."); #endif } else { printf_stderr("Error calling fanotify_init()"); } return; } if (fanotify_mark(mFd, FAN_MARK_ADD | FAN_MARK_MOUNT, FAN_CLOSE, 0, kWatchedPath) < 0) { NS_WARNING("Error calling fanotify_mark"); close(mFd); mFd = -1; return; } if (!MessageLoopForIO::current()->WatchFileDescriptor( mFd, /* persistent = */ true, MessageLoopForIO::WATCH_READ, &mReadWatcher, gHalDiskSpaceWatcher)) { NS_WARNING("Unable to watch fanotify fd."); close(mFd); mFd = -1; } }
static void InitNetdIOThread() { bool result; char propValue[PROPERTY_VALUE_MAX]; MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop()); MOZ_ASSERT(!gNetdClient); property_get("ro.build.version.sdk", propValue, "0"); // Assign rndis address for usb tethering in ICS. if (atoi(propValue) >= 15) { result = InitRndisAddress(); // We don't return here because InitRnsisAddress() function is related to // usb tethering only. Others service such as wifi tethering still need // to use ipc to communicate with netd. if (!result) { LOG("fail to give rndis interface an address"); } } gNetdClient = new NetdClient(); gNetdClient->Start(); }
void Volume::SetMediaPresent(bool aMediaPresent) { MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default); MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop()); // mMediaPresent is slightly redunant to the state, however // when media is removed (while Idle), we get the following: // 631 Volume sdcard /mnt/sdcard disk removed (179:0) // 605 Volume sdcard /mnt/sdcard state changed from 1 (Idle-Unmounted) to 0 (No-Media) // // And on media insertion, we get: // 630 Volume sdcard /mnt/sdcard disk inserted (179:0) // 605 Volume sdcard /mnt/sdcard state changed from 0 (No-Media) to 2 (Pending) // 605 Volume sdcard /mnt/sdcard state changed from 2 (Pending) to 1 (Idle-Unmounted) // // On media removal while the media is mounted: // 632 Volume sdcard /mnt/sdcard bad removal (179:1) // 605 Volume sdcard /mnt/sdcard state changed from 4 (Mounted) to 5 (Unmounting) // 605 Volume sdcard /mnt/sdcard state changed from 5 (Unmounting) to 1 (Idle-Unmounted) // 631 Volume sdcard /mnt/sdcard disk removed (179:0) // 605 Volume sdcard /mnt/sdcard state changed from 1 (Idle-Unmounted) to 0 (No-Media) // // When sharing with a PC, it goes Mounted -> Idle -> Shared // When unsharing with a PC, it goes Shared -> Idle -> Mounted // // The AutoMounter needs to know whether the media is present or not when // processing the Idle state. if (mMediaPresent == aMediaPresent) { return; } LOG("Volume: %s media %s", NameStr(), aMediaPresent ? "inserted" : "removed"); mMediaPresent = aMediaPresent; mEventObserverList.Broadcast(this); }
void TestInterruptShutdownRaceParent::StartShuttingDown() { // NB: we sleep here to try and avoid receiving the Orphan message // while waiting for the CallExit() reply. if we fail at that, it // will cause the test to pass spuriously, because there won't be // an OnMaybeDequeueOne task for Orphan PR_Sleep(2000); if (CallExit()) fail("connection was supposed to be interrupted"); Close(); delete static_cast<TestInterruptShutdownRaceParent*>(gParentActor); gParentActor = nullptr; XRE_GetIOMessageLoop()->PostTask(NewRunnableFunction(DeleteSubprocess)); // this is ordered after the OnMaybeDequeueOne event in the queue MessageLoop::current()->PostTask(NewRunnableFunction(Done)); // |this| has been deleted, be mindful }
CrossProcessCompositorParent::~CrossProcessCompositorParent() { XRE_GetIOMessageLoop()->PostTask(FROM_HERE, new DeleteTask<Transport>(mTransport)); }