diff options
22 files changed, 437 insertions, 139 deletions
diff --git a/cpp/include/Ice/Initialize.h b/cpp/include/Ice/Initialize.h index 15964d54998..f595b126194 100644 --- a/cpp/include/Ice/Initialize.h +++ b/cpp/include/Ice/Initialize.h @@ -659,7 +659,7 @@ public: * Adopts the given communicator. * @param communicator The new communicator instance to hold. */ - explicit CommunicatorHolder(std::shared_ptr<Communicator> communicator); + CommunicatorHolder(std::shared_ptr<Communicator> communicator); /** * Adopts the given communicator. If this holder currently holds a communicator, @@ -869,7 +869,7 @@ public: * Adopts the given communicator. * @param communicator The new communicator instance to hold. */ - explicit CommunicatorHolder(const CommunicatorPtr& communicator); + CommunicatorHolder(const CommunicatorPtr& communicator); /** * Adopts the given communicator. If this holder currently holds a communicator, diff --git a/cpp/src/Glacier2/SessionRouterI.cpp b/cpp/src/Glacier2/SessionRouterI.cpp index e485f76c921..d97f55bcde0 100644 --- a/cpp/src/Glacier2/SessionRouterI.cpp +++ b/cpp/src/Glacier2/SessionRouterI.cpp @@ -1125,7 +1125,12 @@ SessionRouterI::expireSessions() RouterIPtr SessionRouterI::getRouterImpl(const ConnectionPtr& connection, const Ice::Identity& id, bool close) const { - if(_destroy) + // + // The connection can be null if the client tries to forward requests to + // a proxy which points to the client endpoints (in which case the request + // is forwarded with collocation optimization). + // + if(_destroy || !connection) { throw ObjectNotExistException(__FILE__, __LINE__); } diff --git a/cpp/src/Ice/Network.cpp b/cpp/src/Ice/Network.cpp index 09508a02737..9b1b186d56d 100755 --- a/cpp/src/Ice/Network.cpp +++ b/cpp/src/Ice/Network.cpp @@ -780,6 +780,35 @@ getAddressStorageSize(const Address& addr) return size; } +vector<Address> +getLoopbackAddresses(ProtocolSupport protocol, int port = 0) +{ + vector<Address> result; + + Address addr; + memset(&addr.saStorage, 0, sizeof(sockaddr_storage)); + + // + // We don't use getaddrinfo when host is empty as it's not portable (some old Linux + // versions don't support it). + // + if(protocol != EnableIPv4) + { + addr.saIn6.sin6_family = AF_INET6; + addr.saIn6.sin6_port = htons(port); + addr.saIn6.sin6_addr = in6addr_loopback; + result.push_back(addr); + } + if(protocol != EnableIPv6) + { + addr.saIn.sin_family = AF_INET; + addr.saIn.sin_port = htons(port); + addr.saIn.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + result.push_back(addr); + } + return result; +} + #endif // #ifndef ICE_OS_UWP } @@ -1055,9 +1084,6 @@ IceInternal::getAddresses(const string& host, int port, ProtocolSupport protocol bool preferIPv6, bool canBlock) { vector<Address> result; - Address addr; - - memset(&addr.saStorage, 0, sizeof(sockaddr_storage)); // // We don't use getaddrinfo when host is empty as it's not portable (some old Linux @@ -1065,24 +1091,14 @@ IceInternal::getAddresses(const string& host, int port, ProtocolSupport protocol // if(host.empty()) { - if(protocol != EnableIPv4) - { - addr.saIn6.sin6_family = AF_INET6; - addr.saIn6.sin6_port = htons(port); - addr.saIn6.sin6_addr = in6addr_loopback; - result.push_back(addr); - } - if(protocol != EnableIPv6) - { - addr.saIn.sin_family = AF_INET; - addr.saIn.sin_port = htons(port); - addr.saIn.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - result.push_back(addr); - } + result = getLoopbackAddresses(protocol, port); sortAddresses(result, protocol, selType, preferIPv6); return result; } + Address addr; + memset(&addr.saStorage, 0, sizeof(sockaddr_storage)); + struct addrinfo* info = 0; int retry = 5; @@ -1218,7 +1234,8 @@ IceInternal::getAddressForServer(const string& host, int port, ProtocolSupport p #endif return addr; } - vector<Address> addrs = getAddresses(host, port, protocol, Ice::ICE_ENUM(EndpointSelectionType, Ordered), preferIPv6, canBlock); + vector<Address> addrs = getAddresses(host, port, protocol, Ice::ICE_ENUM(EndpointSelectionType, Ordered), + preferIPv6, canBlock); return addrs.empty() ? Address() : addrs[0]; } @@ -1640,7 +1657,7 @@ IceInternal::getHostsForEndpointExpand(const string& host, ProtocolSupport proto hosts.push_back(wstringToString(h->CanonicalName->Data(), getProcessStringConverter())); } } - if(includeLoopback) + if(hosts.empty() || includeLoopback) { if(protocolSupport != EnableIPv6) { @@ -1686,6 +1703,15 @@ IceInternal::getHostsForEndpointExpand(const string& host, ProtocolSupport proto hosts.push_back(inetAddrToString(*p)); } } + if(hosts.empty()) + { + // Return loopback if no other local addresses are available. + addrs = getLoopbackAddresses(protocolSupport); + for(vector<Address>::const_iterator p = addrs.begin(); p != addrs.end(); ++p) + { + hosts.push_back(inetAddrToString(*p)); + } + } } return hosts; // An empty host list indicates to just use the given host. } diff --git a/cpp/test/Glacier2/router/Client.cpp b/cpp/test/Glacier2/router/Client.cpp index 778e02ea4ea..afa70d92013 100644 --- a/cpp/test/Glacier2/router/Client.cpp +++ b/cpp/test/Glacier2/router/Client.cpp @@ -554,6 +554,19 @@ CallbackClient::run(int argc, char* argv[]) cout << "ok" << endl; } + { + cout << "pinging object with client endpoint... " << flush; + Ice::ObjectPrx baseC = communicator()->stringToProxy("collocated:" + getTestEndpoint(communicator(), 50)); + try + { + baseC->ice_ping(); + } + catch(const Ice::ObjectNotExistException&) + { + } + cout << "ok" << endl; + } + CallbackPrx twoway; { diff --git a/cpp/test/uwp/controller/App.xaml.cpp b/cpp/test/uwp/controller/App.xaml.cpp index ea67c113cc6..dfb97c7000d 100644 --- a/cpp/test/uwp/controller/App.xaml.cpp +++ b/cpp/test/uwp/controller/App.xaml.cpp @@ -9,6 +9,7 @@ #include "pch.h" #include "ViewController.xaml.h" +#include <ppltasks.h> using namespace Controller; @@ -25,6 +26,7 @@ using namespace Windows::UI::Xaml::Input; using namespace Windows::UI::Xaml::Interop; using namespace Windows::UI::Xaml::Media; using namespace Windows::UI::Xaml::Navigation; +using namespace Windows::ApplicationModel::ExtendedExecution::Foreground; // The Blank Application template is documented at http://go.microsoft.com/fwlink/?LinkId=234227 @@ -48,20 +50,20 @@ void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEvent { // Do not repeat app initialization when already running, just ensure that // the window is active - if (pArgs->PreviousExecutionState == ApplicationExecutionState::Running) + if(pArgs->PreviousExecutionState == ApplicationExecutionState::Running) { Window::Current->Activate(); return; } - if (pArgs->PreviousExecutionState == ApplicationExecutionState::Terminated) + if(pArgs->PreviousExecutionState == ApplicationExecutionState::Terminated) { //TODO: Load state from previously suspended application } // Create a Frame to act navigation context and navigate to the first page auto rootFrame = ref new Frame(); - if (!rootFrame->Navigate(TypeName(ViewController::typeid))) + if(!rootFrame->Navigate(TypeName(ViewController::typeid))) { throw ref new FailureException("Failed to create initial page"); } @@ -69,6 +71,32 @@ void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEvent // Place the frame in the current Window and ensure that it is active Window::Current->Content = rootFrame; Window::Current->Activate(); + + if(!_session) + { + ExtendedExecutionForegroundSession^ session = ref new ExtendedExecutionForegroundSession(); + session->Reason = ExtendedExecutionForegroundReason::Unconstrained; + session->Revoked += ref new TypedEventHandler<Object^, ExtendedExecutionForegroundRevokedEventArgs^>(this, &App::SessionRevoked); + concurrency::create_task(session->RequestExtensionAsync()).then([this, session](ExtendedExecutionForegroundResult result) + { + switch(result) + { + case ExtendedExecutionForegroundResult::Allowed: + _session = session; + break; + case ExtendedExecutionForegroundResult::Denied: + break; + } + }); + } +} + +void App::SessionRevoked(Object^ sender, ExtendedExecutionForegroundRevokedEventArgs^ args) +{ + if(_session != nullptr) + { + _session = nullptr; + } } /// <summary> diff --git a/cpp/test/uwp/controller/App.xaml.h b/cpp/test/uwp/controller/App.xaml.h index 354d2726504..2305d464a81 100644 --- a/cpp/test/uwp/controller/App.xaml.h +++ b/cpp/test/uwp/controller/App.xaml.h @@ -24,5 +24,7 @@ public: private: void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e); + void SessionRevoked(Platform::Object^, Windows::ApplicationModel::ExtendedExecution::Foreground::ExtendedExecutionForegroundRevokedEventArgs^); + Windows::ApplicationModel::ExtendedExecution::Foreground::ExtendedExecutionForegroundSession^ _session; }; } diff --git a/cpp/test/uwp/controller/Package.appxmanifest b/cpp/test/uwp/controller/Package.appxmanifest index e5a1aa1d6f5..85f47d15719 100644 --- a/cpp/test/uwp/controller/Package.appxmanifest +++ b/cpp/test/uwp/controller/Package.appxmanifest @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp"> +<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" IgnorableNamespaces="uap mp rescap"> <Identity Name="ice-uwp-controller" Publisher="CN=ZeroC" Version="1.0.0.0" /> <mp:PhoneIdentity PhoneProductId="f4c6cdff-3ef9-43fb-8094-d50c547e70f6" PhonePublisherId="00000000-0000-0000-0000-000000000000" /> <Properties> @@ -26,6 +26,8 @@ <Capability Name="internetClientServer" /> <Capability Name="internetClient" /> <Capability Name="privateNetworkClientServer" /> + <rescap:Capability Name="extendedBackgroundTaskTime" /> + <rescap:Capability Name="extendedExecutionUnconstrained" /> </Capabilities> <Extensions> <Extension Category="windows.certificates"> diff --git a/csharp/src/Ice/Network.cs b/csharp/src/Ice/Network.cs index fa64b8d004d..465d0ba35f9 100644 --- a/csharp/src/Ice/Network.cs +++ b/csharp/src/Ice/Network.cs @@ -739,14 +739,20 @@ namespace IceInternal List<EndPoint> addresses = new List<EndPoint>(); if(host.Length == 0) { - if(protocol != EnableIPv4) + foreach(IPAddress a in getLoopbackAddresses(protocol)) { - addresses.Add(new IPEndPoint(IPAddress.IPv6Loopback, port)); + addresses.Add(new IPEndPoint(a, port)); } - - if(protocol != EnableIPv6) + if(protocol == EnableBoth) { - addresses.Add(new IPEndPoint(IPAddress.Loopback, port)); + if(preferIPv6) + { + IceUtilInternal.Collections.Sort(ref addresses, _preferIPv6Comparator); + } + else + { + IceUtilInternal.Collections.Sort(ref addresses, _preferIPv4Comparator); + } } return addresses; } @@ -973,14 +979,21 @@ namespace IceInternal bool ipv4Wildcard = false; if(isWildcard(host, out ipv4Wildcard)) { - IPAddress[] addrs = getLocalAddresses(ipv4Wildcard ? EnableIPv4 : protocol, includeLoopback); - foreach(IPAddress a in addrs) + foreach(IPAddress a in getLocalAddresses(ipv4Wildcard ? EnableIPv4 : protocol, includeLoopback)) { if(!isLinklocal(a)) { hosts.Add(a.ToString()); } } + if(hosts.Count == 0) + { + // Return loopback if only loopback is available no other local addresses are available. + foreach(IPAddress a in getLoopbackAddresses(protocol)) + { + hosts.Add(a.ToString()); + } + } } return hosts; } @@ -991,8 +1004,7 @@ namespace IceInternal bool ipv4Wildcard = false; if(isWildcard(intf, out ipv4Wildcard)) { - IPAddress[] addrs = getLocalAddresses(ipv4Wildcard ? EnableIPv4 : protocol, true); - foreach(IPAddress a in addrs) + foreach(IPAddress a in getLocalAddresses(ipv4Wildcard ? EnableIPv4 : protocol, true)) { interfaces.Add(a.ToString()); } @@ -1245,6 +1257,20 @@ namespace IceInternal return false; } + public static List<IPAddress> getLoopbackAddresses(int protocol) + { + List<IPAddress> addresses = new List<IPAddress>(); + if(protocol != EnableIPv4) + { + addresses.Add(IPAddress.IPv6Loopback); + } + if(protocol != EnableIPv6) + { + addresses.Add(IPAddress.Loopback); + } + return addresses; + } + public static bool addressEquals(EndPoint addr1, EndPoint addr2) { diff --git a/csharp/test/Glacier2/router/Client.cs b/csharp/test/Glacier2/router/Client.cs index a996bb0275a..795aaeb730a 100644 --- a/csharp/test/Glacier2/router/Client.cs +++ b/csharp/test/Glacier2/router/Client.cs @@ -165,6 +165,19 @@ public class Client : TestCommon.Application Console.Out.WriteLine("ok"); } + { + Console.Out.Write("pinging object with client endpoint... "); + Ice.ObjectPrx baseC = communicator().stringToProxy("collocated:" + getTestEndpoint(50)); + try + { + baseC.ice_ping(); + } + catch(Ice.ObjectNotExistException) + { + } + Console.Out.WriteLine("ok"); + } + CallbackPrx twoway; { diff --git a/java-compat/src/Ice/src/main/java/IceInternal/Network.java b/java-compat/src/Ice/src/main/java/IceInternal/Network.java index 14c50c52e40..a58df9bcf5c 100644 --- a/java-compat/src/Ice/src/main/java/IceInternal/Network.java +++ b/java-compat/src/Ice/src/main/java/IceInternal/Network.java @@ -880,7 +880,7 @@ public final class Network // Iterate over the network interfaces and pick an IP // address (preferably not the loopback address). // - java.util.ArrayList<java.net.InetAddress> addrs = getLocalAddresses(protocol); + java.util.ArrayList<java.net.InetAddress> addrs = getLocalAddresses(protocol, false); java.util.Iterator<java.net.InetAddress> iter = addrs.iterator(); while(addr == null && iter.hasNext()) { @@ -983,7 +983,7 @@ public final class Network } public static java.util.ArrayList<java.net.InetAddress> - getLocalAddresses(int protocol) + getLocalAddresses(int protocol, boolean includeLoopback) { java.util.ArrayList<java.net.InetAddress> result = new java.util.ArrayList<java.net.InetAddress>(); try @@ -996,7 +996,7 @@ public final class Network while(addrs.hasMoreElements()) { java.net.InetAddress addr = addrs.nextElement(); - if(!addr.isLoopbackAddress()) + if(includeLoopback || !addr.isLoopbackAddress()) { if(protocol == EnableBoth || isValidAddr(addr, protocol)) { @@ -1047,8 +1047,7 @@ public final class Network java.util.ArrayList<String> hosts = new java.util.ArrayList<String>(); if(isWildcard(host)) { - java.util.ArrayList<java.net.InetAddress> addrs = getLocalAddresses(protocolSupport); - for(java.net.InetAddress addr : addrs) + for(java.net.InetAddress addr : getLocalAddresses(protocolSupport, includeLoopback)) { // // NOTE: We don't publish link-local IPv6 addresses as these addresses can only @@ -1059,17 +1058,12 @@ public final class Network hosts.add(addr.getHostAddress()); } } - - if(includeLoopback || hosts.isEmpty()) + if(hosts.isEmpty()) { - if(protocolSupport != EnableIPv6) - { - hosts.add("127.0.0.1"); - } - - if(protocolSupport != EnableIPv4) + // Return loopback if no other local addresses are available. + for(java.net.InetAddress addr : getLoopbackAddresses(protocolSupport)) { - hosts.add("0:0:0:0:0:0:0:1"); + hosts.add(addr.getHostAddress()); } } } @@ -1082,19 +1076,10 @@ public final class Network java.util.ArrayList<String> interfaces = new java.util.ArrayList<>(); if(isWildcard(intf)) { - java.util.ArrayList<java.net.InetAddress> addrs = getLocalAddresses(protocolSupport); - for(java.net.InetAddress addr : addrs) + for(java.net.InetAddress addr : getLocalAddresses(protocolSupport, true)) { interfaces.add(addr.getHostAddress()); } - if(protocolSupport != EnableIPv6) - { - interfaces.add("127.0.0.1"); - } - if(protocolSupport != EnableIPv4) - { - interfaces.add("0:0:0:0:0:0:0:1"); - } } if(interfaces.isEmpty()) { diff --git a/java-compat/test/src/main/java/test/Glacier2/router/Client.java b/java-compat/test/src/main/java/test/Glacier2/router/Client.java index 7d932ab0465..15bd713e670 100644 --- a/java-compat/test/src/main/java/test/Glacier2/router/Client.java +++ b/java-compat/test/src/main/java/test/Glacier2/router/Client.java @@ -189,6 +189,20 @@ public class Client extends test.Util.Application out.println("ok"); } + { + out.print("pinging object with client endpoint... "); + out.flush(); + Ice.ObjectPrx baseC = communicator().stringToProxy("collocated:" + getTestEndpoint(50)); + try + { + baseC.ice_ping(); + } + catch(Ice.ObjectNotExistException ex) + { + } + out.println("ok"); + } + CallbackPrx twoway; { diff --git a/java/src/Ice/src/main/java/com/zeroc/IceInternal/Network.java b/java/src/Ice/src/main/java/com/zeroc/IceInternal/Network.java index cb56f0bb9e1..0a66898acf5 100644 --- a/java/src/Ice/src/main/java/com/zeroc/IceInternal/Network.java +++ b/java/src/Ice/src/main/java/com/zeroc/IceInternal/Network.java @@ -885,7 +885,7 @@ public final class Network // Iterate over the network interfaces and pick an IP // address (preferably not the loopback address). // - java.util.ArrayList<java.net.InetAddress> addrs = getLocalAddresses(protocol); + java.util.ArrayList<java.net.InetAddress> addrs = getLocalAddresses(protocol, false); java.util.Iterator<java.net.InetAddress> iter = addrs.iterator(); while(addr == null && iter.hasNext()) { @@ -988,7 +988,7 @@ public final class Network } public static java.util.ArrayList<java.net.InetAddress> - getLocalAddresses(int protocol) + getLocalAddresses(int protocol, boolean includeLoopback) { java.util.ArrayList<java.net.InetAddress> result = new java.util.ArrayList<>(); try @@ -1001,7 +1001,7 @@ public final class Network while(addrs.hasMoreElements()) { java.net.InetAddress addr = addrs.nextElement(); - if(!addr.isLoopbackAddress()) + if(includeLoopback || !addr.isLoopbackAddress()) { if(protocol == EnableBoth || isValidAddr(addr, protocol)) { @@ -1052,8 +1052,7 @@ public final class Network java.util.ArrayList<String> hosts = new java.util.ArrayList<>(); if(isWildcard(host)) { - java.util.ArrayList<java.net.InetAddress> addrs = getLocalAddresses(protocolSupport); - for(java.net.InetAddress addr : addrs) + for(java.net.InetAddress addr : getLocalAddresses(protocolSupport, includeLoopback)) { // // NOTE: We don't publish link-local IPv6 addresses as these addresses can only @@ -1064,17 +1063,12 @@ public final class Network hosts.add(addr.getHostAddress()); } } - - if(includeLoopback || hosts.isEmpty()) + if(hosts.isEmpty()) { - if(protocolSupport != EnableIPv6) - { - hosts.add("127.0.0.1"); - } - - if(protocolSupport != EnableIPv4) + // Return loopback if no other local addresses are available. + for(java.net.InetAddress addr : getLoopbackAddresses(protocolSupport)) { - hosts.add("0:0:0:0:0:0:0:1"); + hosts.add(addr.getHostAddress()); } } } @@ -1087,19 +1081,10 @@ public final class Network java.util.ArrayList<String> interfaces = new java.util.ArrayList<>(); if(isWildcard(intf)) { - java.util.ArrayList<java.net.InetAddress> addrs = getLocalAddresses(protocolSupport); - for(java.net.InetAddress addr : addrs) + for(java.net.InetAddress addr : getLocalAddresses(protocolSupport, true)) { interfaces.add(addr.getHostAddress()); } - if(protocolSupport != EnableIPv6) - { - interfaces.add("127.0.0.1"); - } - if(protocolSupport != EnableIPv4) - { - interfaces.add("0:0:0:0:0:0:0:1"); - } } if(interfaces.isEmpty()) { diff --git a/java/test/src/main/java/test/Glacier2/router/Client.java b/java/test/src/main/java/test/Glacier2/router/Client.java index a083c860c3b..0ffbeabee2c 100644 --- a/java/test/src/main/java/test/Glacier2/router/Client.java +++ b/java/test/src/main/java/test/Glacier2/router/Client.java @@ -186,6 +186,20 @@ public class Client extends test.Util.Application out.println("ok"); } + { + out.print("pinging object with client endpoint... "); + out.flush(); + com.zeroc.Ice.ObjectPrx baseC = communicator().stringToProxy("collocated:" + getTestEndpoint(50)); + try + { + baseC.ice_ping(); + } + catch(com.zeroc.Ice.ObjectNotExistException ex) + { + } + out.println("ok"); + } + CallbackPrx twoway; { diff --git a/js/test/Glacier2/router/Client.js b/js/test/Glacier2/router/Client.js index 76db6a620db..9ea97bf1ec5 100644 --- a/js/test/Glacier2/router/Client.js +++ b/js/test/Glacier2/router/Client.js @@ -141,6 +141,19 @@ await base.ice_ping(); out.writeLine("ok"); + { + out.write("pinging object with client endpoint... "); + const baseC = communicator.stringToProxy("collocated:default -p 12060"); + try + { + await baseC.ice_ping(); + } + catch(ex) + { + } + out.writeLine("ok"); + } + out.write("testing checked cast for server object... "); let twoway = await Test.CallbackPrx.checkedCast(base); test(twoway !== null); diff --git a/matlab/lib/+Ice/ObjectPrx.m b/matlab/lib/+Ice/ObjectPrx.m index bda1e88b6da..387dc692a85 100644 --- a/matlab/lib/+Ice/ObjectPrx.m +++ b/matlab/lib/+Ice/ObjectPrx.m @@ -95,8 +95,12 @@ classdef ObjectPrx < IceInternal.WrapperObject % proxy, but uses batch datagram invocations. % ice_compress - Returns a proxy that is identical to this proxy, % except for compression. + % ice_getCompress - Obtains the compression override setting of this proxy. % ice_timeout - Returns a proxy that is identical to this proxy, % except for its connection timeout setting. + % ice_getTimeout - Obtains the timeout override of this proxy. + % ice_fixed - Obtains a proxy that is identical to this proxy, except it's + % a fixed proxy bound to the given connection. % ice_getConnection - Returns the Connection for this proxy. % ice_getConnectionAsync - Returns the Connection for this proxy. % ice_getCachedConnection - Returns the cached Connection for this @@ -810,7 +814,7 @@ classdef ObjectPrx < IceInternal.WrapperObject % b (logical) - True enables compression for the new proxy; % false disables compression. % - % Returns - A proxy with the specified compression setting. + % Returns - A proxy with the specified compression override setting. if b val = 1; @@ -820,12 +824,29 @@ classdef ObjectPrx < IceInternal.WrapperObject r = obj.factory_('ice_compress', true, val); end + function r = ice_getCompress(obj) + % ice_getCompress - Obtains the compression override setting of this proxy. + % + % Returns (optional bool) - The compression override setting. If Ice.Unset + % is returned, no override is set. Otherwise, true if compression is + % enabled, false otherwise. + + obj.instantiate_(); + opt = obj.iceCallWithResult('ice_getCompress'); + if opt.hasValue + r = opt.value; + else + r = Ice.Unset; + end + end + function r = ice_timeout(obj, t) % ice_timeout - Returns a proxy that is identical to this proxy, - % except for its connection timeout setting. + % except for its connection timeout setting which overrides the timeout + % setting from the proxy endpoints. % % Parameters: - % t (int32) - The connection timeout for the proxy in + % t (int32) - The connection override timeout for the proxy in % milliseconds. % % Returns - A proxy with the specified timeout. @@ -833,6 +854,38 @@ classdef ObjectPrx < IceInternal.WrapperObject r = obj.factory_('ice_timeout', true, t); end + function r = ice_getTimeout(obj) + % ice_getTimeout - Obtains the timeout override of this proxy. + % + % Returns (optional int32) - The timeout override. If Ice.Unset + % is returned, no override is set. Otherwise, returns the + % timeout override value. + + obj.instantiate_(); + opt = obj.iceCallWithResult('ice_getTimeout'); + if opt.hasValue + r = opt.value; + else + r = Ice.Unset; + end + end + + function r = ice_fixed(obj, connection) + % ice_fixed - Obtains a proxy that is identical to this proxy, except it's + % a fixed proxy bound to the given connection. + % + % Parameters: + % connection (Ice.Connection) - The fixed proxy connection. + % + % Returns (Ice.ObjectPrx) - A fixed proxy bound to the given connection. + + if isempty(connection) + throw(MException('Ice:ArgumentException', 'invalid null connection passed to ice_fixed')); + end + + r = obj.factory_('ice_fixed', true, connection.iceGetImpl()); + end + function r = ice_getConnection(obj) % ice_getConnection - Returns the Connection for this proxy. If the % proxy does not yet have an established connection, it first diff --git a/matlab/lib/+IceInternal/WrapperObject.m b/matlab/lib/+IceInternal/WrapperObject.m index aaecc47d153..3d12d9a8a25 100644 --- a/matlab/lib/+IceInternal/WrapperObject.m +++ b/matlab/lib/+IceInternal/WrapperObject.m @@ -47,6 +47,9 @@ classdef (Abstract) WrapperObject < handle r = result.result; end end + function r = iceGetImpl(obj) + r = obj.impl_; + end end properties(Hidden,SetAccess=protected) impl_ diff --git a/matlab/src/ObjectPrx.cpp b/matlab/src/ObjectPrx.cpp index f7b2a5e842c..d6261c9269d 100644 --- a/matlab/src/ObjectPrx.cpp +++ b/matlab/src/ObjectPrx.cpp @@ -966,6 +966,20 @@ Ice_ObjectPrx_ice_compress(void* self, void** r, unsigned char b) } mxArray* +Ice_ObjectPrx_ice_getCompress(void* self) +{ + auto v = deref<Ice::ObjectPrx>(self)->ice_getCompress(); + if(v.has_value()) + { + return createResultValue(createOptionalValue(true, createBool(v.value()))); + } + else + { + return createResultValue(createOptionalValue(false, 0)); + } +} + +mxArray* Ice_ObjectPrx_ice_timeout(void* self, void** r, int t) { try @@ -982,6 +996,37 @@ Ice_ObjectPrx_ice_timeout(void* self, void** r, int t) } mxArray* +Ice_ObjectPrx_ice_getTimeout(void* self) +{ + auto v = deref<Ice::ObjectPrx>(self)->ice_getTimeout(); + if(v.has_value()) + { + return createResultValue(createOptionalValue(true, createInt(v.value()))); + } + else + { + return createResultValue(createOptionalValue(false, 0)); + } +} + +mxArray* +Ice_ObjectPrx_ice_fixed(void* self, void** r, void* connection) +{ + assert(connection); // Wrapper only calls this function for non-nil arguments. + try + { + auto proxy = deref<Ice::ObjectPrx>(self); + auto newProxy = proxy->ice_fixed(deref<Ice::Connection>(connection)); + *r = newProxy == proxy ? 0 : new shared_ptr<Ice::ObjectPrx>(move(newProxy)); + } + catch(const std::exception& ex) + { + return convertException(ex); + } + return 0; +} + +mxArray* Ice_ObjectPrx_ice_getConnection(void* self, void** r) { *r = 0; diff --git a/matlab/src/Util.cpp b/matlab/src/Util.cpp index 2ddc7e6dc1d..3e1e92998ac 100644 --- a/matlab/src/Util.cpp +++ b/matlab/src/Util.cpp @@ -535,6 +535,21 @@ IceMatlab::createResultException(mxArray* ex) return r; } +static const char* optionalFields[] = {"hasValue", "value"}; + +mxArray* +IceMatlab::createOptionalValue(bool hasValue, mxArray* value) +{ + mwSize dims[2] = {1, 1}; + auto r = mxCreateStructArray(2, dims, 2, optionalFields); + mxSetFieldByNumber(r, 0, 0, createBool(hasValue)); + if(hasValue) + { + mxSetFieldByNumber(r, 0, 1, value); + } + return r; +} + mxArray* IceMatlab::createStringList(const vector<string>& v) { diff --git a/matlab/src/Util.h b/matlab/src/Util.h index a29b3c78987..89b5f38e30f 100644 --- a/matlab/src/Util.h +++ b/matlab/src/Util.h @@ -39,6 +39,7 @@ void getEncodingVersion(mxArray*, Ice::EncodingVersion&); mxArray* convertException(const std::exception&); mxArray* createResultValue(mxArray*); mxArray* createResultException(mxArray*); +mxArray* createOptionalValue(bool, mxArray*); mxArray* createStringList(const std::vector<std::string>&); void getStringList(mxArray*, std::vector<std::string>&); mxArray* createByteArray(const Ice::Byte*, const Ice::Byte*); diff --git a/matlab/src/ice.h b/matlab/src/ice.h index 08a4ddb4947..7d47d4ed5f0 100644 --- a/matlab/src/ice.h +++ b/matlab/src/ice.h @@ -103,7 +103,10 @@ ICE_MATLAB_API mxArray* Ice_ObjectPrx_ice_datagram(void*, void**); ICE_MATLAB_API mxArray* Ice_ObjectPrx_ice_isBatchDatagram(void*); ICE_MATLAB_API mxArray* Ice_ObjectPrx_ice_batchDatagram(void*, void**); ICE_MATLAB_API mxArray* Ice_ObjectPrx_ice_compress(void*, void**, unsigned char); +ICE_MATLAB_API mxArray* Ice_ObjectPrx_ice_getCompress(void*); ICE_MATLAB_API mxArray* Ice_ObjectPrx_ice_timeout(void*, void**, int); +ICE_MATLAB_API mxArray* Ice_ObjectPrx_ice_getTimeout(void*); +ICE_MATLAB_API mxArray* Ice_ObjectPrx_ice_fixed(void*, void**, void*); ICE_MATLAB_API mxArray* Ice_ObjectPrx_ice_getConnection(void*, void**); ICE_MATLAB_API mxArray* Ice_ObjectPrx_ice_getConnectionAsync(void*, void**); ICE_MATLAB_API mxArray* Ice_ObjectPrx_ice_getCachedConnection(void*, void**); diff --git a/matlab/test/Ice/proxy/AllTests.m b/matlab/test/Ice/proxy/AllTests.m index 3f61bb9f96a..d29412ec661 100644 --- a/matlab/test/Ice/proxy/AllTests.m +++ b/matlab/test/Ice/proxy/AllTests.m @@ -530,11 +530,19 @@ classdef AllTests %assert(compObj.ice_compress(false) < compObj.ice_compress(true)); %assert(~(compObj.ice_compress(true) < compObj.ice_compress(false))); + assert(compObj.ice_getCompress() == Ice.Unset); + assert(compObj.ice_compress(true).ice_getCompress() == true); + assert(compObj.ice_compress(false).ice_getCompress() == false); + assert(compObj.ice_timeout(20) == compObj.ice_timeout(20)); assert(compObj.ice_timeout(10) ~= compObj.ice_timeout(20)); %assert(compObj.ice_timeout(10) < compObj.ice_timeout(20)); %assert(~(compObj.ice_timeout(20) < compObj.ice_timeout(10))); + assert(compObj.ice_getTimeout() == Ice.Unset); + assert(compObj.ice_timeout(10).ice_getTimeout() == 10); + assert(compObj.ice_timeout(20).ice_getTimeout() == 20); + loc1 = Ice.LocatorPrx.uncheckedCast(communicator.stringToProxy('loc1:default -p 10000')); loc2 = Ice.LocatorPrx.uncheckedCast(communicator.stringToProxy('loc2:default -p 10000')); assert(compObj.ice_locator([]) == compObj.ice_locator([])); @@ -622,9 +630,13 @@ classdef AllTests %assert(~(compObj.ice_encodingVersion(Ice.EncodingVersion(1, 1)) < ... % compObj.ice_encodingVersion(Ice.EncodingVersion(1, 0)))); - % - % TODO: Ideally we should also test comparison of fixed proxies. - % + baseConnection = base.ice_getConnection(); + if ~isempty(baseConnection) + baseConnection2 = base.ice_connectionId('base2').ice_getConnection(); + compObj1 = compObj1.ice_fixed(baseConnection); + compObj2 = compObj2.ice_fixed(baseConnection2); + assert(compObj1 ~= compObj2); + end fprintf('ok\n'); @@ -666,6 +678,51 @@ classdef AllTests assert(isequal(c, c2)); fprintf('ok\n'); + fprintf('testing ice_fixed... '); + connection = cl.ice_getConnection(); + if ~isempty(connection) + prx = cl.ice_fixed(connection); % Test factory method return type + prx.ice_ping(); + assert(cl.ice_secure(true).ice_fixed(connection).ice_isSecure()); + assert(strcmp(cl.ice_facet('facet').ice_fixed(connection).ice_getFacet(), 'facet')); + assert(cl.ice_oneway().ice_fixed(connection).ice_isOneway()); + ctx = containers.Map('KeyType', 'char', 'ValueType', 'char'); + ctx('one') = 'hello'; + ctx('two') = 'world'; + assert(isempty(cl.ice_fixed(connection).ice_getContext())); + assert(cl.ice_context(ctx).ice_fixed(connection).ice_getContext().length() == 2); + assert(cl.ice_fixed(connection).ice_getInvocationTimeout() == -1); + assert(cl.ice_invocationTimeout(10).ice_fixed(connection).ice_getInvocationTimeout() == 10); + assert(cl.ice_fixed(connection).ice_getConnection() == connection); + assert(cl.ice_fixed(connection).ice_fixed(connection).ice_getConnection() == connection); + assert(cl.ice_compress(true).ice_fixed(connection).ice_getCompress() == true); + assert(cl.ice_fixed(connection).ice_getTimeout() == Ice.Unset); + fixedConnection = cl.ice_connectionId('ice_fixed').ice_getConnection(); + assert(cl.ice_fixed(connection).ice_fixed(fixedConnection).ice_getConnection() == fixedConnection); + try + cl.ice_secure(~connection.getEndpoint().getInfo().secure()).ice_fixed(connection).ice_ping(); + catch ex + if ~isa(ex, 'Ice.NoEndpointException') + rethrow(ex); + end + end + try + cl.ice_datagram().ice_fixed(connection).ice_ping(); + catch ex + if ~isa(ex, 'Ice.NoEndpointException') + rethrow(ex); + end + end + else + try + cl.ice_fixed(connection); + assert(false); + catch ex + % Expected with null connection. + end + end + fprintf('ok\n'); + fprintf('testing encoding versioning... '); ref20 = 'test -e 2.0:default -p 12010'; cl20 = MyClassPrx.uncheckedCast(communicator.stringToProxy(ref20)); diff --git a/scripts/Util.py b/scripts/Util.py index 114c389f542..0332efa2f74 100644 --- a/scripts/Util.py +++ b/scripts/Util.py @@ -940,9 +940,6 @@ class Mapping: else: return exe - def getCommandLineWithArgs(self, current, process, exe, args): - return self.getCommandLine(current, process, exe) + " " + args - def getProps(self, process, current): props = {} if isinstance(process, IceProcess): @@ -1239,9 +1236,6 @@ class Process(Runnable): def getCommandLine(self, current): return self.getMapping(current).getCommandLine(current, self, self.getExe(current)) - def getCommandLineWithArgs(self, current, args): - return self.getMapping(current).getCommandLineWithArgs(current, self, self.getExe(current), args) - # # A simple client (used to run Slice/IceUtil clients for example) # @@ -1953,8 +1947,8 @@ class LocalProcessController(ProcessController): if current.driver.valgrind: cmd += "valgrind -q --child-silent-after-fork=yes --leak-check=full --suppressions=\"{0}\" ".format( os.path.join(toplevel, "config", "valgrind.sup")) - exe = process.getCommandLineWithArgs(current, (" " + " ".join(args) if len(args) > 0 else "").format(**kargs)) - cmd += exe + exe = process.getCommandLine(current) + cmd += (exe + (" " + " ".join(args) if len(args) > 0 else "")).format(**kargs) if current.driver.debug: if len(envs) > 0: @@ -2655,7 +2649,7 @@ class Driver: @classmethod def getSupportedArgs(self): return ("dlrR", ["debug", "driver=", "filter=", "rfilter=", "host=", "host-ipv6=", "host-bt=", "interface=", - "controller-app", "valgrind", "languages="]) + "controller-app", "valgrind", "languages=", "rlanguages="]) @classmethod def usage(self): @@ -2670,6 +2664,7 @@ class Driver: print("--filter=<regex> Run all the tests that match the given regex.") print("--rfilter=<regex> Run all the tests that do not match the given regex.") print("--languages=l1,l2,... List of comma-separated language mappings to test.") + print("--rlanguages=l1,l2,.. List of comma-separated language mappings to not test.") print("--host=<addr> The IPv4 address to use for Ice.Default.Host.") print("--host-ipv6=<addr> The IPv6 address to use for Ice.Default.Host.") print("--host-bt=<addr> The Bluetooth address to use for Ice.Default.Host.") @@ -2687,6 +2682,7 @@ class Driver: self.controllerApp = False self.valgrind = False self.languages = [] + self.rlanguages = [] self.failures = [] parseOptions(self, options, { "d": "debug", @@ -2702,6 +2698,8 @@ class Driver: self.rfilters = [re.compile(a) for a in self.rfilters] if self.languages: self.languages = [i for sublist in [l.split(",") for l in self.languages] for i in sublist] + if self.rlanguages: + self.rlanguages = [i for sublist in [l.split(",") for l in self.rlanguages] for i in sublist] self.communicator = None self.interface = "" @@ -2760,8 +2758,12 @@ class Driver: ### Return additional mappings to load required by the driver return [] - def getLanguages(self): - return self.languages + def matchLanguage(self, language): + if self.languages and language not in self.languages: + return False + if self.rlanguages and language in self.rlanguages: + return False + return True def getCommunicator(self): self.initCommunicator() @@ -3470,23 +3472,21 @@ class MatlabMapping(CppBasedClientMapping): mappingName = "matlab" mappingDesc = "MATLAB" - def getCommandLineWithArgs(self, current, process, exe, args): - return "matlab -nodesktop -nosplash -wait -log -minimize -r \"cd '{0}', runTest {1} {2} {3}\"".format( + def getCommandLine(self, current, process, exe): + return "matlab -nodesktop -nosplash -wait -log -minimize -r \"cd '{0}', runTest {1} {2}\"".format( os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "matlab", "test", "lib")), self.getTestCwd(process, current), - os.path.join(current.config.buildPlatform, current.config.buildConfig), - args) + os.path.join(current.config.buildPlatform, current.config.buildConfig)) def getDefaultSource(self, processType): return { "client" : "client.m" }[processType] def getOptions(self, current): # - # Metrics tests configuration not supported with MATLAB - # they use the Admin adapter. + # Metrics tests configuration not supported with MATLAB they use the Admin adapter. # options = CppBasedClientMapping.getOptions(self, current) - options["mx"] = [False] + options["mx"] = [ False ] return options class JavaScriptMapping(Mapping): @@ -3593,29 +3593,6 @@ except ImportError: from LocalDriver import * # -# Check if the .NET Core SDK is installed -# -# -# Check if the Android SDK is installed by looking for adb -# -hasDotnetSDK=False -try: - run("dotnet --version") - hasDotnetSDK=True -except: - pass - -# -# Check if the Android SDK is installed by looking for adb -# -hasAndroidSDK=False -try: - run("adb version") - hasAndroidSDK=True -except: - pass - -# # Supported mappings # for m in filter(lambda x: os.path.isdir(os.path.join(toplevel, x)), os.listdir(toplevel)): @@ -3631,19 +3608,39 @@ for m in filter(lambda x: os.path.isdir(os.path.join(toplevel, x)), os.listdir(t Mapping.add(m, RubyMapping()) elif m == "php" or re.match("php-.*", m): Mapping.add(m, PhpMapping()) - elif m == "matlab" or re.match("matlab-.*", m): - Mapping.add(m, MatlabMapping()) elif m == "js" or re.match("js-.*", m): Mapping.add(m, JavaScriptMapping()) elif m == "objective-c" or re.match("objective-c-*", m): Mapping.add(m, ObjCMapping()) -if isinstance(platform, Windows) or hasDotnetSDK: +try: + if not isinstance(platform, Windows): + # + # Check if the .NET Core SDK is installed + # + run("dotnet --version"): Mapping.add("csharp", CSharpMapping()) +except: + pass -if hasAndroidSDK: +# +# Check if the Android SDK is installed and eventually add the Android mappings +# +try: + run("adb version") Mapping.add(os.path.join("java-compat", "android"), AndroidCompatMapping()) Mapping.add(os.path.join("java", "android"), AndroidMapping()) +except: + pass + +# +# Check if Matlab is installed and eventually add the Matlab mapping +# +try: + run("where matlab" if isinstance(platform, Windows) else "which matlab") + Mapping.add("matlab", MatlabMapping()) +except: + pass def runTestsWithPath(path): runTests([Mapping.getByPath(path)]) @@ -3693,8 +3690,7 @@ def runTests(mappings=None, drivers=None): driver = Driver.create(opts) # - # Create the configurations for each mapping (we always parse the configuration for the - # python mapping because we might use the local IcePy build to initialize a communicator). + # Create the configurations for each mapping. # configs = {} for mapping in Mapping.getAll(): @@ -3702,10 +3698,9 @@ def runTests(mappings=None, drivers=None): configs[mapping] = mapping.createConfig(opts[:]) # - # If the user specified --languages, only run matching mappings. + # If the user specified --languages/rlanguages, only run matching mappings. # - if driver.getLanguages(): - mappings = [Mapping.getByName(l) for l in driver.getLanguages()] + mappings = [m for m in mappings if driver.matchLanguage(str(m))] # # Provide the configurations to the driver and load the test suites for each mapping. |