Skip to content

Commit

Permalink
[LocationSync] Fix deadlock with OOP plugins (#261)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebaszm authored Nov 10, 2023
1 parent 32b1722 commit 896acd2
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 34 deletions.
34 changes: 25 additions & 9 deletions LocationSync/LocationService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,22 +488,22 @@ POP_WARNING()
} else {
_publicIPAddress = _infoCarrier->IP();
}
_state = LOADED;


ASSERT(!_publicIPAddress.empty());

Core::NodeId node(_publicIPAddress.c_str(), Core::NodeId::TYPE_UNSPECIFIED);

if (node.IsValid() != true) {
_state = FAILED;
TRACE(Trace::Information, (_T("Could not determine the external public IP address [%s]"), _publicIPAddress.c_str()));
}
else {
if (node.Type() == Core::NodeId::TYPE_IPV4) {
Core::NodeId::ClearIPV6Enabled();
}

TRACE(Trace::Information, (_T("Network connectivity established. Type: %s, on %s"), (node.Type() == Core::NodeId::TYPE_IPV6 ? _T("IPv6") : _T("IPv4")), node.HostAddress().c_str()));
_callback->Dispatch();
_state = LOADING;
}

ASSERT(_infoCarrier.IsValid() == true);
Expand Down Expand Up @@ -543,6 +543,8 @@ POP_WARNING()
void LocationService::Dispatch()
{
uint32_t result = Core::infinite;
bool dispatch = false;

TRACE(Trace::Information, (_T("LocationService: job is dispatched")));

if ((Close(100) != Core::ERROR_NONE) || (IsClosed() == false)) {
Expand All @@ -561,7 +563,7 @@ POP_WARNING()
}
}

if ((_state != LOADED) && (_state != FAILED)) {
if ((_state != LOADING) && (_state != LOADED) && (_state != FAILED)) {

Core::NodeId remote(_remoteId.c_str(), ((_state == ACTIVE) && (Core::NodeId::IsIPV6Enabled()) ? Core::NodeId::TYPE_IPV6 : Core::NodeId::TYPE_IPV4));

Expand Down Expand Up @@ -599,17 +601,31 @@ POP_WARNING()
}
}

if (_state == FAILED) {

if (_state == LOADING) {
_state = LOADED;

Core::NodeId node(_publicIPAddress.c_str(), Core::NodeId::TYPE_UNSPECIFIED);

TRACE(Trace::Information, (_T("Network connectivity established. Type: %s, on %s"),
(node.Type() == Core::NodeId::TYPE_IPV6 ? _T("IPv6") : _T("IPv4")), node.HostAddress().c_str()));

dispatch = true;
}
else if (_state == FAILED) {
Core::NodeId::ClearIPV6Enabled();

TRACE(Trace::Error, (_T("LocationSync: Network connectivity could *NOT* be established. Falling back to IPv4. %d"), __LINE__));

_infoCarrier.Release();

dispatch = true;
}

_adminLock.Unlock();
}

if (_state == FAILED) {
Core::NodeId::ClearIPV6Enabled();

TRACE(Trace::Error, (_T("LocationSync: Network connectivity could *NOT* be established. Falling back to IPv4. %d"), __LINE__));
if (dispatch == true) {
_callback->Dispatch();
}

Expand Down
1 change: 1 addition & 0 deletions LocationSync/LocationService.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ namespace Plugin {
ACTIVE,
IPV6_INPROGRESS,
IPV4_INPROGRESS,
LOADING,
LOADED,
FAILED
};
Expand Down
43 changes: 27 additions & 16 deletions LocationSync/LocationSync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,24 +155,35 @@ POP_WARNING()
Core::ProxyType<Web::JSONBodyType<Data>> response(jsonResponseFactory.Element());

PluginHost::ISubSystem* subSystem = _service->SubSystems();

ASSERT(subSystem != nullptr);

const PluginHost::ISubSystem::IInternet* internet(subSystem->Get<PluginHost::ISubSystem::IInternet>());
const PluginHost::ISubSystem::ILocation* location(subSystem->Get<PluginHost::ISubSystem::ILocation>());

if ((internet != nullptr) && (location != nullptr)) {
response->PublicIp = internet->PublicIPAddress();
response->TimeZone = location->TimeZone();
response->Region = location->Region();
response->Country = location->Country();
response->City = location->City();

result->ContentType = Web::MIMETypes::MIME_JSON;
result->Body(Core::ProxyType<Web::IBody>(response));
} else {
result->ErrorCode = Web::STATUS_SERVICE_UNAVAILABLE;
result->Message = _T("Internet and Location Service not yet available");
if (subSystem != nullptr) {
const PluginHost::ISubSystem::IInternet* internet(subSystem->Get<PluginHost::ISubSystem::IInternet>());

if (internet != nullptr) {
response->PublicIp = internet->PublicIPAddress();

const PluginHost::ISubSystem::ILocation* location(subSystem->Get<PluginHost::ISubSystem::ILocation>());

if (location != nullptr) {
response->TimeZone = location->TimeZone();
response->Region = location->Region();
response->Country = location->Country();
response->City = location->City();

location->Release();
}

result->ContentType = Web::MIMETypes::MIME_JSON;
result->Body(Core::ProxyType<Web::IBody>(response));

internet->Release();
} else {
result->ErrorCode = Web::STATUS_SERVICE_UNAVAILABLE;
result->Message = _T("Internet and Location Service not yet available");
}

subSystem->Release();
}
} else if (request.Verb == Web::Request::HTTP_POST) {
index.Next();
Expand Down
30 changes: 21 additions & 9 deletions LocationSync/LocationSyncJsonRpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,32 @@ namespace Plugin {
uint32_t LocationSync::get_location(LocationData& response) const
{
uint32_t status = Core::ERROR_UNAVAILABLE;

PluginHost::ISubSystem* subSystem = _service->SubSystems();
ASSERT(subSystem != nullptr);

const PluginHost::ISubSystem::IInternet* internet(subSystem->Get<PluginHost::ISubSystem::IInternet>());
const PluginHost::ISubSystem::ILocation* location(subSystem->Get<PluginHost::ISubSystem::ILocation>());
if (subSystem != nullptr) {
const PluginHost::ISubSystem::IInternet* internet(subSystem->Get<PluginHost::ISubSystem::IInternet>());

if (internet != nullptr) {
response.Publicip = internet->PublicIPAddress();

const PluginHost::ISubSystem::ILocation* location(subSystem->Get<PluginHost::ISubSystem::ILocation>());

if (location != nullptr) {
response.Timezone = location->TimeZone();
response.Region = location->Region();
response.Country = location->Country();
response.City = location->City();

location->Release();
}

if ((internet != nullptr) && (location != nullptr)) {
response.Publicip = internet->PublicIPAddress();
status = Core::ERROR_NONE;
internet->Release();
}

response.Timezone = location->TimeZone();
response.Region = location->Region();
response.Country = location->Country();
response.City = location->City();
status = Core::ERROR_NONE;
subSystem->Release();
}

return status;
Expand Down

0 comments on commit 896acd2

Please sign in to comment.