Bug 795658 - Make sure most methods are running from main thread. r=dougt

This commit is contained in:
Kan-Ru Chen (陳侃如) 2012-10-04 10:00:59 +08:00
parent d309e30f04
commit feef09a102
2 changed files with 76 additions and 41 deletions

View File

@ -37,7 +37,10 @@ using namespace mozilla;
static const int kDefaultPeriod = 1000; // ms
NS_IMPL_ISUPPORTS2(GonkGPSGeolocationProvider, nsIGeolocationProvider, nsIRILDataCallback)
// While most methods of GonkGPSGeolocationProvider should only be
// called from main thread, we deliberately put the Init and ShutdownGPS
// methods off main thread to avoid blocking.
NS_IMPL_THREADSAFE_ISUPPORTS2(GonkGPSGeolocationProvider, nsIGeolocationProvider, nsIRILDataCallback)
GonkGPSGeolocationProvider* GonkGPSGeolocationProvider::sSingleton;
GpsCallbacks GonkGPSGeolocationProvider::mCallbacks = {
@ -126,19 +129,29 @@ GonkGPSGeolocationProvider::NmeaCallback(GpsUtcTime timestamp, const char* nmea,
void
GonkGPSGeolocationProvider::SetCapabilitiesCallback(uint32_t capabilities)
{
// Called by GPS engine in init(), hence we don't have to
// protect the memebers
class UpdateCapabilitiesEvent : public nsRunnable {
public:
UpdateCapabilitiesEvent(uint32_t aCapabilities)
: mCapabilities(aCapabilities)
{}
NS_IMETHOD Run() {
nsRefPtr<GonkGPSGeolocationProvider> provider =
GonkGPSGeolocationProvider::GetSingleton();
nsRefPtr<GonkGPSGeolocationProvider> provider =
GonkGPSGeolocationProvider::GetSingleton();
provider->mSupportsScheduling = capabilities & GPS_CAPABILITY_SCHEDULING;
provider->mSupportsMSB = capabilities & GPS_CAPABILITY_MSB;
provider->mSupportsMSA = capabilities & GPS_CAPABILITY_MSA;
provider->mSupportsSingleShot = capabilities & GPS_CAPABILITY_SINGLE_SHOT;
provider->mSupportsScheduling = mCapabilities & GPS_CAPABILITY_SCHEDULING;
provider->mSupportsMSB = mCapabilities & GPS_CAPABILITY_MSB;
provider->mSupportsMSA = mCapabilities & GPS_CAPABILITY_MSA;
provider->mSupportsSingleShot = mCapabilities & GPS_CAPABILITY_SINGLE_SHOT;
#ifdef GPS_CAPABILITY_ON_DEMAND_TIME
provider->mSupportsTimeInjection = capabilities & GPS_CAPABILITY_ON_DEMAND_TIME;
provider->mSupportsTimeInjection = mCapabilities & GPS_CAPABILITY_ON_DEMAND_TIME;
#endif
return NS_OK;
}
private:
uint32_t mCapabilities;
};
NS_DispatchToMainThread(new UpdateCapabilitiesEvent(capabilities));
}
void
@ -181,21 +194,30 @@ GonkGPSGeolocationProvider::AGPSStatusCallback(AGpsStatus* status)
{
MOZ_ASSERT(status);
nsRefPtr<GonkGPSGeolocationProvider> provider =
GonkGPSGeolocationProvider::GetSingleton();
class AGPSStatusEvent : public nsRunnable {
public:
AGPSStatusEvent(AGpsStatusValue aStatus)
: mStatus(aStatus)
{}
NS_IMETHOD Run() {
nsRefPtr<GonkGPSGeolocationProvider> provider =
GonkGPSGeolocationProvider::GetSingleton();
nsCOMPtr<nsIRunnable> event;
switch (status->status) {
case GPS_REQUEST_AGPS_DATA_CONN:
event = NS_NewRunnableMethod(provider, &GonkGPSGeolocationProvider::RequestDataConnection);
break;
case GPS_RELEASE_AGPS_DATA_CONN:
event = NS_NewRunnableMethod(provider, &GonkGPSGeolocationProvider::ReleaseDataConnection);
break;
}
if (event) {
NS_DispatchToMainThread(event);
}
switch (mStatus) {
case GPS_REQUEST_AGPS_DATA_CONN:
provider->RequestDataConnection();
break;
case GPS_RELEASE_AGPS_DATA_CONN:
provider->ReleaseDataConnection();
break;
}
return NS_OK;
}
private:
AGpsStatusValue mStatus;
};
NS_DispatchToMainThread(new AGPSStatusEvent(status->status));
}
void
@ -245,13 +267,17 @@ GonkGPSGeolocationProvider::GonkGPSGeolocationProvider()
GonkGPSGeolocationProvider::~GonkGPSGeolocationProvider()
{
ShutdownNow();
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mStarted, "Must call Shutdown before destruction");
sSingleton = nullptr;
}
already_AddRefed<GonkGPSGeolocationProvider>
GonkGPSGeolocationProvider::GetSingleton()
{
MOZ_ASSERT(NS_IsMainThread());
if (!sSingleton)
sSingleton = new GonkGPSGeolocationProvider();
@ -283,6 +309,8 @@ GonkGPSGeolocationProvider::GetGPSInterface()
void
GonkGPSGeolocationProvider::RequestDataConnection()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mRIL) {
return;
}
@ -304,6 +332,8 @@ GonkGPSGeolocationProvider::RequestDataConnection()
void
GonkGPSGeolocationProvider::ReleaseDataConnection()
{
MOZ_ASSERT(NS_IsMainThread());
if (!mRIL) {
return;
}
@ -421,6 +451,7 @@ GonkGPSGeolocationProvider::Init()
void
GonkGPSGeolocationProvider::StartGPS()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mGpsInterface);
int32_t update = Preferences::GetInt("geo.default.update", kDefaultPeriod);
@ -457,7 +488,7 @@ void
GonkGPSGeolocationProvider::SetupAGPS()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mAGpsRilInterface);
MOZ_ASSERT(mAGpsInterface);
const nsAdoptingCString& suplServer = Preferences::GetCString("geo.gps.supl_server");
int32_t suplPort = Preferences::GetInt("geo.gps.supl_port", -1);
@ -483,6 +514,8 @@ GonkGPSGeolocationProvider::SetupAGPS()
NS_IMETHODIMP
GonkGPSGeolocationProvider::Startup()
{
MOZ_ASSERT(NS_IsMainThread());
if (mStarted) {
return NS_OK;
}
@ -502,6 +535,8 @@ GonkGPSGeolocationProvider::Startup()
NS_IMETHODIMP
GonkGPSGeolocationProvider::Watch(nsIGeolocationUpdate* aCallback)
{
MOZ_ASSERT(NS_IsMainThread());
mLocationCallback = aCallback;
return NS_OK;
}
@ -509,30 +544,29 @@ GonkGPSGeolocationProvider::Watch(nsIGeolocationUpdate* aCallback)
NS_IMETHODIMP
GonkGPSGeolocationProvider::Shutdown()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mInitThread);
if (!mStarted) {
return NS_OK;
}
mInitThread->Dispatch(NS_NewRunnableMethod(this, &GonkGPSGeolocationProvider::ShutdownNow),
NS_DISPATCH_NORMAL);
return NS_OK;
}
void
GonkGPSGeolocationProvider::ShutdownNow()
{
if (!mStarted) {
return;
}
mStarted = false;
if (mRIL) {
mRIL->UnregisterDataCallCallback(this);
}
mInitThread->Dispatch(NS_NewRunnableMethod(this, &GonkGPSGeolocationProvider::ShutdownGPS),
NS_DISPATCH_NORMAL);
return NS_OK;
}
void
GonkGPSGeolocationProvider::ShutdownGPS()
{
MOZ_ASSERT(!mStarted, "Should only be called after Shutdown");
if (mGpsInterface) {
mGpsInterface->stop();
mGpsInterface->cleanup();
@ -552,6 +586,7 @@ GonkGPSGeolocationProvider::SetHighAccuracy(bool)
NS_IMETHODIMP
GonkGPSGeolocationProvider::DataCallStateChanged(nsIRILDataCallInfo* aDataCall)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aDataCall);
MOZ_ASSERT(mAGpsInterface);
nsCOMPtr<nsIRILDataCallInfo> datacall = aDataCall;

View File

@ -63,7 +63,7 @@ private:
void Init();
void SetupAGPS();
void StartGPS();
void ShutdownNow();
void ShutdownGPS();
void RequestDataConnection();
void ReleaseDataConnection();
void RequestSetID(uint32_t flags);