зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1008091 - Send network change events on FxOS and Linux. r=sworkman
This commit is contained in:
Родитель
11eb2398e3
Коммит
a7f268f4f7
|
@ -58,6 +58,11 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
|
||||||
'../system/android',
|
'../system/android',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
elif CONFIG['OS_ARCH'] == 'Linux':
|
||||||
|
LOCAL_INCLUDES += [
|
||||||
|
'../system/linux',
|
||||||
|
]
|
||||||
|
|
||||||
if CONFIG['NECKO_COOKIES']:
|
if CONFIG['NECKO_COOKIES']:
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
'../cookie',
|
'../cookie',
|
||||||
|
|
|
@ -376,6 +376,9 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsQtNetworkLinkService, Init)
|
||||||
#elif defined(MOZ_WIDGET_ANDROID)
|
#elif defined(MOZ_WIDGET_ANDROID)
|
||||||
#include "nsAndroidNetworkLinkService.h"
|
#include "nsAndroidNetworkLinkService.h"
|
||||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAndroidNetworkLinkService)
|
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAndroidNetworkLinkService)
|
||||||
|
#elif defined(XP_LINUX)
|
||||||
|
#include "nsNotifyAddrListener_Linux.h"
|
||||||
|
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsNotifyAddrListener, Init)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -791,6 +794,8 @@ NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
|
||||||
NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
|
NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
|
||||||
#elif defined(MOZ_WIDGET_ANDROID)
|
#elif defined(MOZ_WIDGET_ANDROID)
|
||||||
NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
|
NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
|
||||||
|
#elif defined(XP_LINUX)
|
||||||
|
NS_DEFINE_NAMED_CID(NS_NETWORK_LINK_SERVICE_CID);
|
||||||
#endif
|
#endif
|
||||||
NS_DEFINE_NAMED_CID(NS_SERIALIZATION_HELPER_CID);
|
NS_DEFINE_NAMED_CID(NS_SERIALIZATION_HELPER_CID);
|
||||||
NS_DEFINE_NAMED_CID(NS_REDIRECTCHANNELREGISTRAR_CID);
|
NS_DEFINE_NAMED_CID(NS_REDIRECTCHANNELREGISTRAR_CID);
|
||||||
|
@ -935,6 +940,8 @@ static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
|
||||||
{ &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsQtNetworkLinkServiceConstructor },
|
{ &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsQtNetworkLinkServiceConstructor },
|
||||||
#elif defined(MOZ_WIDGET_ANDROID)
|
#elif defined(MOZ_WIDGET_ANDROID)
|
||||||
{ &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsAndroidNetworkLinkServiceConstructor },
|
{ &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsAndroidNetworkLinkServiceConstructor },
|
||||||
|
#elif defined(XP_LINUX)
|
||||||
|
{ &kNS_NETWORK_LINK_SERVICE_CID, false, nullptr, nsNotifyAddrListenerConstructor },
|
||||||
#endif
|
#endif
|
||||||
{ &kNS_SERIALIZATION_HELPER_CID, false, nullptr, nsSerializationHelperConstructor },
|
{ &kNS_SERIALIZATION_HELPER_CID, false, nullptr, nsSerializationHelperConstructor },
|
||||||
{ &kNS_REDIRECTCHANNELREGISTRAR_CID, false, nullptr, RedirectChannelRegistrarConstructor },
|
{ &kNS_REDIRECTCHANNELREGISTRAR_CID, false, nullptr, RedirectChannelRegistrarConstructor },
|
||||||
|
@ -1082,6 +1089,8 @@ static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
|
||||||
{ NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
|
{ NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
|
||||||
#elif defined(MOZ_WIDGET_ANDROID)
|
#elif defined(MOZ_WIDGET_ANDROID)
|
||||||
{ NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
|
{ NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
|
||||||
|
#elif defined(XP_LINUX)
|
||||||
|
{ NS_NETWORK_LINK_SERVICE_CONTRACTID, &kNS_NETWORK_LINK_SERVICE_CID },
|
||||||
#endif
|
#endif
|
||||||
{ NS_SERIALIZATION_HELPER_CONTRACTID, &kNS_SERIALIZATION_HELPER_CID },
|
{ NS_SERIALIZATION_HELPER_CONTRACTID, &kNS_SERIALIZATION_HELPER_CID },
|
||||||
{ NS_REDIRECTCHANNELREGISTRAR_CONTRACTID, &kNS_REDIRECTCHANNELREGISTRAR_CID },
|
{ NS_REDIRECTCHANNELREGISTRAR_CONTRACTID, &kNS_REDIRECTCHANNELREGISTRAR_CID },
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||||
|
# vim: set filetype=python:
|
||||||
|
# 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/.
|
||||||
|
|
||||||
|
if CONFIG['OS_ARCH'] == 'Linux':
|
||||||
|
SOURCES += [
|
||||||
|
'nsNotifyAddrListener_Linux.cpp',
|
||||||
|
]
|
||||||
|
|
||||||
|
FAIL_ON_WARNINGS = True
|
||||||
|
|
||||||
|
FINAL_LIBRARY = 'xul'
|
|
@ -0,0 +1,318 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/* vim:set et sw=4 ts=4: */
|
||||||
|
/* 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 <stdarg.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "nsThreadUtils.h"
|
||||||
|
#include "nsIObserverService.h"
|
||||||
|
#include "nsServiceManagerUtils.h"
|
||||||
|
#include "nsNotifyAddrListener_Linux.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsAutoPtr.h"
|
||||||
|
#include "prlog.h"
|
||||||
|
|
||||||
|
#include "mozilla/Services.h"
|
||||||
|
#include "mozilla/Preferences.h"
|
||||||
|
#include "mozilla/FileUtils.h"
|
||||||
|
|
||||||
|
#ifdef MOZ_WIDGET_GONK
|
||||||
|
#include <cutils/properties.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* a shorter name that better explains what it does */
|
||||||
|
#define EINTR_RETRY(x) MOZ_TEMP_FAILURE_RETRY(x)
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
|
#if defined(PR_LOGGING)
|
||||||
|
static PRLogModuleInfo *gNotifyAddrLog = nullptr;
|
||||||
|
#define LOG(args) PR_LOG(gNotifyAddrLog, PR_LOG_DEBUG, args)
|
||||||
|
#else
|
||||||
|
#define LOG(args)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NETWORK_NOTIFY_CHANGED_PREF "network.notify.changed"
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS(nsNotifyAddrListener,
|
||||||
|
nsINetworkLinkService,
|
||||||
|
nsIRunnable,
|
||||||
|
nsIObserver)
|
||||||
|
|
||||||
|
nsNotifyAddrListener::nsNotifyAddrListener()
|
||||||
|
: mLinkUp(true) // assume true by default
|
||||||
|
, mStatusKnown(false)
|
||||||
|
, mAllowChangedEvent(true)
|
||||||
|
, mChildThreadShutdown(false)
|
||||||
|
{
|
||||||
|
mShutdownPipe[0] = -1;
|
||||||
|
mShutdownPipe[1] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsNotifyAddrListener::~nsNotifyAddrListener()
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!mThread, "nsNotifyAddrListener thread shutdown failed");
|
||||||
|
|
||||||
|
if (mShutdownPipe[0] != -1) {
|
||||||
|
EINTR_RETRY(close(mShutdownPipe[0]));
|
||||||
|
}
|
||||||
|
if (mShutdownPipe[1] != -1) {
|
||||||
|
EINTR_RETRY(close(mShutdownPipe[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNotifyAddrListener::GetIsLinkUp(bool *aIsUp)
|
||||||
|
{
|
||||||
|
// XXX This function has not yet been implemented for this platform
|
||||||
|
*aIsUp = mLinkUp;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNotifyAddrListener::GetLinkStatusKnown(bool *aIsUp)
|
||||||
|
{
|
||||||
|
// XXX This function has not yet been implemented for this platform
|
||||||
|
*aIsUp = mStatusKnown;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNotifyAddrListener::GetLinkType(uint32_t *aLinkType)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_POINTER(aLinkType);
|
||||||
|
|
||||||
|
// XXX This function has not yet been implemented for this platform
|
||||||
|
*aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nsNotifyAddrListener::OnNetlinkMessage(int aNetlinkSocket)
|
||||||
|
{
|
||||||
|
struct nlmsghdr *nlh;
|
||||||
|
struct rtmsg *route_entry;
|
||||||
|
|
||||||
|
// The buffer size below, (4095) was chosen partly based on testing and
|
||||||
|
// partly on existing sample source code using this size. It needs to be
|
||||||
|
// large enough to hold the netlink messages from the kernel.
|
||||||
|
char buffer[4095];
|
||||||
|
|
||||||
|
// Receiving netlink socket data
|
||||||
|
ssize_t rc = EINTR_RETRY(recv(aNetlinkSocket, buffer, sizeof(buffer), 0));
|
||||||
|
if (rc < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t netlink_bytes = rc;
|
||||||
|
|
||||||
|
nlh = reinterpret_cast<struct nlmsghdr *>(buffer);
|
||||||
|
|
||||||
|
bool networkChange = false;
|
||||||
|
|
||||||
|
for (; NLMSG_OK(nlh, netlink_bytes);
|
||||||
|
nlh = NLMSG_NEXT(nlh, netlink_bytes)) {
|
||||||
|
|
||||||
|
if (NLMSG_DONE == nlh->nlmsg_type) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(nlh->nlmsg_type) {
|
||||||
|
case RTM_DELROUTE:
|
||||||
|
case RTM_NEWROUTE:
|
||||||
|
// Get the route data
|
||||||
|
route_entry = static_cast<struct rtmsg *>(NLMSG_DATA(nlh));
|
||||||
|
|
||||||
|
// We are just intrested in main routing table
|
||||||
|
if (route_entry->rtm_table != RT_TABLE_MAIN)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
networkChange = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTM_NEWADDR:
|
||||||
|
networkChange = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (networkChange && mAllowChangedEvent) {
|
||||||
|
SendEvent(NS_NETWORK_LINK_DATA_CHANGED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNotifyAddrListener::Run()
|
||||||
|
{
|
||||||
|
PR_SetCurrentThreadName("Link Monitor");
|
||||||
|
|
||||||
|
int netlinkSocket = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||||
|
if (netlinkSocket < 0) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_nl addr;
|
||||||
|
memset(&addr, 0, sizeof(addr)); // clear addr
|
||||||
|
|
||||||
|
addr.nl_family = AF_NETLINK;
|
||||||
|
addr.nl_groups = RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR |
|
||||||
|
RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE;
|
||||||
|
|
||||||
|
if (bind(netlinkSocket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||||
|
// failure!
|
||||||
|
EINTR_RETRY(close(netlinkSocket));
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// switch the socket into non-blocking
|
||||||
|
int flags = fcntl(netlinkSocket, F_GETFL, 0);
|
||||||
|
(void)fcntl(netlinkSocket, F_SETFL, flags | O_NONBLOCK);
|
||||||
|
|
||||||
|
struct pollfd fds[2];
|
||||||
|
fds[0].fd = mShutdownPipe[0];
|
||||||
|
fds[0].events = POLLIN;
|
||||||
|
fds[0].revents = 0;
|
||||||
|
|
||||||
|
fds[1].fd = netlinkSocket;
|
||||||
|
fds[1].events = POLLIN;
|
||||||
|
fds[1].revents = 0;
|
||||||
|
|
||||||
|
// when in b2g emulator, work around bug 1112499
|
||||||
|
int pollTimeout = -1;
|
||||||
|
#ifdef MOZ_WIDGET_GONK
|
||||||
|
char propQemu[PROPERTY_VALUE_MAX];
|
||||||
|
property_get("ro.kernel.qemu", propQemu, "");
|
||||||
|
pollTimeout = !strncmp(propQemu, "1", 1) ? 100 : -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
bool shutdown = false;
|
||||||
|
while (!shutdown) {
|
||||||
|
int rc = EINTR_RETRY(poll(fds, 2, pollTimeout));
|
||||||
|
|
||||||
|
if (rc > 0) {
|
||||||
|
if (fds[0].revents & POLLIN) {
|
||||||
|
// shutdown, abort the loop!
|
||||||
|
LOG(("thread shutdown received, dying...\n"));
|
||||||
|
shutdown = true;
|
||||||
|
} else if (fds[1].revents & POLLIN) {
|
||||||
|
LOG(("netlink message received, handling it...\n"));
|
||||||
|
OnNetlinkMessage(netlinkSocket);
|
||||||
|
}
|
||||||
|
} else if (rc < 0) {
|
||||||
|
rv = NS_ERROR_FAILURE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (mChildThreadShutdown) {
|
||||||
|
LOG(("thread shutdown via variable, dying...\n"));
|
||||||
|
shutdown = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EINTR_RETRY(close(netlinkSocket));
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNotifyAddrListener::Observe(nsISupports *subject,
|
||||||
|
const char *topic,
|
||||||
|
const char16_t *data)
|
||||||
|
{
|
||||||
|
if (!strcmp("xpcom-shutdown-threads", topic)) {
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsNotifyAddrListener::Init(void)
|
||||||
|
{
|
||||||
|
#if defined(PR_LOGGING)
|
||||||
|
if (!gNotifyAddrLog)
|
||||||
|
gNotifyAddrLog = PR_NewLogModule("nsNotifyAddr");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nsCOMPtr<nsIObserverService> observerService =
|
||||||
|
mozilla::services::GetObserverService();
|
||||||
|
if (!observerService)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsresult rv = observerService->AddObserver(this, "xpcom-shutdown-threads",
|
||||||
|
false);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
Preferences::AddBoolVarCache(&mAllowChangedEvent,
|
||||||
|
NETWORK_NOTIFY_CHANGED_PREF, true);
|
||||||
|
|
||||||
|
rv = NS_NewThread(getter_AddRefs(mThread), this);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (-1 == pipe(mShutdownPipe)) {
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsNotifyAddrListener::Shutdown(void)
|
||||||
|
{
|
||||||
|
// remove xpcom shutdown observer
|
||||||
|
nsCOMPtr<nsIObserverService> observerService =
|
||||||
|
mozilla::services::GetObserverService();
|
||||||
|
if (observerService)
|
||||||
|
observerService->RemoveObserver(this, "xpcom-shutdown-threads");
|
||||||
|
|
||||||
|
LOG(("write() to signal thread shutdown\n"));
|
||||||
|
|
||||||
|
// awake the thread to make it terminate
|
||||||
|
ssize_t rc = EINTR_RETRY(write(mShutdownPipe[1], "1", 1));
|
||||||
|
LOG(("write() returned %d, errno == %d\n", (int)rc, errno));
|
||||||
|
|
||||||
|
mChildThreadShutdown = true;
|
||||||
|
|
||||||
|
nsresult rv = mThread->Shutdown();
|
||||||
|
|
||||||
|
// Have to break the cycle here, otherwise nsNotifyAddrListener holds
|
||||||
|
// onto the thread and the thread holds onto the nsNotifyAddrListener
|
||||||
|
// via its mRunnable
|
||||||
|
mThread = nullptr;
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sends the given event. Assumes aEventID never goes out of scope (static
|
||||||
|
* strings are ideal).
|
||||||
|
*/
|
||||||
|
nsresult
|
||||||
|
nsNotifyAddrListener::SendEvent(const char *aEventID)
|
||||||
|
{
|
||||||
|
if (!aEventID)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
nsCOMPtr<nsIRunnable> event = new ChangeEvent(this, aEventID);
|
||||||
|
if (NS_FAILED(rv = NS_DispatchToMainThread(event)))
|
||||||
|
NS_WARNING("Failed to dispatch ChangeEvent");
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsNotifyAddrListener::ChangeEvent::Run()
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIObserverService> observerService =
|
||||||
|
mozilla::services::GetObserverService();
|
||||||
|
if (observerService)
|
||||||
|
observerService->NotifyObservers(
|
||||||
|
mService, NS_NETWORK_LINK_TOPIC,
|
||||||
|
NS_ConvertASCIItoUTF16(mEventID).get());
|
||||||
|
return NS_OK;
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/* vim:set et sw=4 ts=4: */
|
||||||
|
/* 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/. */
|
||||||
|
#ifndef NSNOTIFYADDRLISTENER_LINUX_H_
|
||||||
|
#define NSNOTIFYADDRLISTENER_LINUX_H_
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
#include <linux/rtnetlink.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "nsINetworkLinkService.h"
|
||||||
|
#include "nsIRunnable.h"
|
||||||
|
#include "nsIObserver.h"
|
||||||
|
#include "nsThreadUtils.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
#include "mozilla/TimeStamp.h"
|
||||||
|
|
||||||
|
class nsNotifyAddrListener : public nsINetworkLinkService,
|
||||||
|
public nsIRunnable,
|
||||||
|
public nsIObserver
|
||||||
|
{
|
||||||
|
virtual ~nsNotifyAddrListener();
|
||||||
|
|
||||||
|
public:
|
||||||
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
|
NS_DECL_NSINETWORKLINKSERVICE
|
||||||
|
NS_DECL_NSIRUNNABLE
|
||||||
|
NS_DECL_NSIOBSERVER
|
||||||
|
|
||||||
|
nsNotifyAddrListener();
|
||||||
|
nsresult Init(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
class ChangeEvent : public nsRunnable {
|
||||||
|
public:
|
||||||
|
NS_DECL_NSIRUNNABLE
|
||||||
|
ChangeEvent(nsINetworkLinkService *aService, const char *aEventID)
|
||||||
|
: mService(aService), mEventID(aEventID) {
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
nsCOMPtr<nsINetworkLinkService> mService;
|
||||||
|
const char *mEventID;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Called when xpcom-shutdown-threads is received.
|
||||||
|
nsresult Shutdown(void);
|
||||||
|
|
||||||
|
// Sends the network event.
|
||||||
|
nsresult SendEvent(const char *aEventID);
|
||||||
|
|
||||||
|
// Deals with incoming NETLINK messages.
|
||||||
|
void OnNetlinkMessage(int NetlinkSocket);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIThread> mThread;
|
||||||
|
|
||||||
|
// The network is up.
|
||||||
|
bool mLinkUp;
|
||||||
|
|
||||||
|
// The network's up/down status is known.
|
||||||
|
bool mStatusKnown;
|
||||||
|
|
||||||
|
// A pipe to signal shutdown with.
|
||||||
|
int mShutdownPipe[2];
|
||||||
|
|
||||||
|
// Network changed events are enabled
|
||||||
|
bool mAllowChangedEvent;
|
||||||
|
|
||||||
|
// Flag to signal child thread kill with
|
||||||
|
bool mChildThreadShutdown;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* NSNOTIFYADDRLISTENER_LINUX_H_ */
|
|
@ -16,3 +16,5 @@ if CONFIG['MOZ_ENABLE_QTNETWORK']:
|
||||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
|
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
|
||||||
DIRS += ['android']
|
DIRS += ['android']
|
||||||
|
|
||||||
|
elif CONFIG['OS_ARCH'] == 'Linux':
|
||||||
|
DIRS += ['linux']
|
||||||
|
|
|
@ -161,6 +161,16 @@ void ReadAhead(filedesc_t aFd, const size_t aOffset = 0,
|
||||||
const size_t aCount = SIZE_MAX);
|
const size_t aCount = SIZE_MAX);
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(MOZ_WIDGET_GONK) || defined(XP_UNIX)
|
||||||
|
#define MOZ_TEMP_FAILURE_RETRY(exp) (__extension__({ \
|
||||||
|
typeof (exp) _rc; \
|
||||||
|
do { \
|
||||||
|
_rc = (exp); \
|
||||||
|
} while (_rc == -1 && errno == EINTR); \
|
||||||
|
_rc; \
|
||||||
|
}))
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Define ReadSysFile() only on GONK to avoid unnecessary lubxul bloat.
|
/* Define ReadSysFile() only on GONK to avoid unnecessary lubxul bloat.
|
||||||
Also define it in debug builds, so that unit tests for it can be written
|
Also define it in debug builds, so that unit tests for it can be written
|
||||||
and run in non-GONK builds. */
|
and run in non-GONK builds. */
|
||||||
|
@ -170,14 +180,6 @@ and run in non-GONK builds. */
|
||||||
#define ReadSysFile_PRESENT
|
#define ReadSysFile_PRESENT
|
||||||
#endif /* ReadSysFile_PRESENT */
|
#endif /* ReadSysFile_PRESENT */
|
||||||
|
|
||||||
#define MOZ_TEMP_FAILURE_RETRY(exp) (__extension__({ \
|
|
||||||
typeof (exp) _rc; \
|
|
||||||
do { \
|
|
||||||
_rc = (exp); \
|
|
||||||
} while (_rc == -1 && errno == EINTR); \
|
|
||||||
_rc; \
|
|
||||||
}))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the contents of a file.
|
* Read the contents of a file.
|
||||||
* This function is intended for reading a single-lined text files from
|
* This function is intended for reading a single-lined text files from
|
||||||
|
|
Загрузка…
Ссылка в новой задаче