Example #1
0
IceInternal::TcpTransceiver::TcpTransceiver(const InstancePtr& instance, SOCKET fd, bool connected) :
    NativeInfo(fd),
    _traceLevels(instance->traceLevels()),
    _logger(instance->initializationData().logger),
    _stats(instance->initializationData().stats),
    _state(connected ? StateConnected : StateNeedConnect),
    _desc(connected ? fdToString(_fd) : string())
#ifdef ICE_USE_IOCP
    , _read(SocketOperationRead), 
    _write(SocketOperationWrite)
#endif
{
    setBlock(_fd, false);

    setTcpBufSize(_fd, instance->initializationData().properties, _logger);

#ifdef ICE_USE_IOCP
    //
    // On Windows, limiting the buffer size is important to prevent
    // poor throughput performances when transfering large amount of
    // data. See Microsoft KB article KB823764.
    //
    _maxSendPacketSize = IceInternal::getSendBufferSize(fd) / 2;
    if(_maxSendPacketSize < 512)
    {
        _maxSendPacketSize = 0;
    }

    _maxReceivePacketSize = IceInternal::getRecvBufferSize(fd);
    if(_maxReceivePacketSize < 512)
    {
        _maxReceivePacketSize = 0;
    }
#endif
}
Example #2
0
IceInternal::TcpAcceptor::TcpAcceptor(const InstancePtr& instance, const string& host, int port, ProtocolSupport protocol) :
    _instance(instance),
    _traceLevels(instance->traceLevels()),
    _logger(instance->initializationData().logger),
    _addr(getAddressForServer(host, port, protocol))
#ifdef ICE_USE_IOCP
    , _acceptFd(INVALID_SOCKET),
    _info(SocketOperationRead)
#endif
{
#ifdef SOMAXCONN
    _backlog = instance->initializationData().properties->getPropertyAsIntWithDefault("Ice.TCP.Backlog", SOMAXCONN);
#else
    _backlog = instance->initializationData().properties->getPropertyAsIntWithDefault("Ice.TCP.Backlog", 511);
#endif

    _fd = createSocket(false, _addr.ss_family);
#ifdef ICE_USE_IOCP
    _acceptBuf.resize((sizeof(sockaddr_storage) + 16) * 2);
#endif
    setBlock(_fd, false);
    setTcpBufSize(_fd, _instance->initializationData().properties, _logger);
#ifndef _WIN32
    //
    // Enable SO_REUSEADDR on Unix platforms to allow re-using the
    // socket even if it's in the TIME_WAIT state. On Windows,
    // this doesn't appear to be necessary and enabling
    // SO_REUSEADDR would actually not be a good thing since it
    // allows a second process to bind to an address even it's
    // already bound by another process.
    //
    // TODO: using SO_EXCLUSIVEADDRUSE on Windows would probably
    // be better but it's only supported by recent Windows
    // versions (XP SP2, Windows Server 2003).
    //
    setReuseAddress(_fd, true);
#endif
    if(_traceLevels->network >= 2)
    {
        Trace out(_logger, _traceLevels->networkCat);
        out << "attempting to bind to tcp socket " << toString();
    }
    const_cast<struct sockaddr_storage&>(_addr) = doBind(_fd, _addr);
}
Example #3
0
IceInternal::TcpConnector::TcpConnector(const InstancePtr& instance, const Address& addr,
                                        Ice::Int timeout, const string& connectionId) :
    _instance(instance),
    _traceLevels(instance->traceLevels()),
    _logger(instance->initializationData().logger),
    _addr(addr),
    _timeout(timeout),
    _connectionId(connectionId)
{
}
Example #4
0
BatchRequestQueue::BatchRequestQueue(const InstancePtr& instance, bool datagram) :
    _interceptor(instance->initializationData().batchRequestInterceptor),
    _batchStream(instance.get(), Ice::currentProtocolEncoding),
    _batchStreamInUse(false),
    _batchStreamCanFlush(false),
    _batchRequestNum(0)
{
    _batchStream.writeBlob(requestBatchHdr, sizeof(requestBatchHdr));
    _batchMarker = _batchStream.b.size();

    _maxSize = instance->batchAutoFlushSize();
    if(_maxSize > 0 && datagram)
    {
        const Ice::InitializationData& initData = instance->initializationData();
        size_t udpSndSize = initData.properties->getPropertyAsIntWithDefault("Ice.UDP.SndSize", 65535 - udpOverhead);
        if(udpSndSize < _maxSize)
        {
            _maxSize = udpSndSize;
        }
    }
}
Example #5
0
Ice::ObjectAdapterI::ObjectAdapterI(const InstancePtr& instance, const CommunicatorPtr& communicator,
                                    const ObjectAdapterFactoryPtr& objectAdapterFactory, const string& name,
                                    const string& endpointInfo, const RouterPrx& router, bool noConfig) :
    _deactivated(false),
    _instance(instance),
    _communicator(communicator),
    _objectAdapterFactory(objectAdapterFactory),
    _servantManager(new ServantManager(instance, name)),
    _activateOneOffDone(false),
    _name(name),
    _directCount(0),
    _waitForActivate(false),
    _destroying(false),
    _destroyed(false),
    _noConfig(noConfig),
    _threadPerConnection(false),
    _threadPerConnectionStackSize(0)
{
    if(_noConfig)
    {
        return;
    }

    PropertiesPtr properties = instance->initializationData().properties;
    StringSeq unknownProps;
    bool noProps = filterProperties(unknownProps);

    //
    // Warn about unknown object adapter properties.
    //
    if(unknownProps.size() != 0 && properties->getPropertyAsIntWithDefault("Ice.Warn.UnknownProperties", 1) > 0)
    {
        Warning out(_instance->initializationData().logger);
        out << "found unknown properties for object adapter '" << _name << "':";
        for(unsigned int i = 0; i < unknownProps.size(); ++i)
        {
            out << "\n    " << unknownProps[i];
        }
    }

    //
    // Make sure named adapter has some configuration
    //
    if(endpointInfo.empty() && router == 0 && noProps)
    {
        InitializationException ex(__FILE__, __LINE__);
        ex.reason = "object adapter \"" + _name + "\" requires configuration.";
        throw ex;
    }

    const_cast<string&>(_id) = properties->getProperty(_name + ".AdapterId");
    const_cast<string&>(_replicaGroupId) = properties->getProperty(_name + ".ReplicaGroupId");

    __setNoDelete(true);
    try
    {
        _threadPerConnection = properties->getPropertyAsInt(_name + ".ThreadPerConnection") > 0;

        int threadPoolSize = properties->getPropertyAsInt(_name + ".ThreadPool.Size");
        int threadPoolSizeMax = properties->getPropertyAsInt(_name + ".ThreadPool.SizeMax");
        if(_threadPerConnection && (threadPoolSize > 0 || threadPoolSizeMax > 0))
        {
            InitializationException ex(__FILE__, __LINE__);
            ex.reason = "object adapter \"" + _name + "\" cannot be configured for both\n"
                "thread pool and thread per connection";
            throw ex;
        }

        if(!_threadPerConnection && threadPoolSize == 0 && threadPoolSizeMax == 0)
        {
            _threadPerConnection = _instance->threadPerConnection();
        }

        if(_threadPerConnection)
        {
            int stackSize = 
                properties->getPropertyAsIntWithDefault(_name + ".ThreadPerConnection.StackSize",
                                                        static_cast<Int>(_instance->threadPerConnectionStackSize()));
            if(stackSize < 0)
            {
                stackSize = 0;
            }
            _threadPerConnectionStackSize = stackSize;
        }

        //
        // Create the per-adapter thread pool, if necessary. This is done before the creation of the incoming
        // connection factory as the thread pool is needed during creation for the call to incFdsInUse.
        //
        if(threadPoolSize > 0 || threadPoolSizeMax > 0)
        {
            _threadPool = new ThreadPool(_instance, _name + ".ThreadPool", 0);
        }

        if(!router)
        {
            const_cast<RouterPrx&>(router) = RouterPrx::uncheckedCast(
                _instance->proxyFactory()->propertyToProxy(_name + ".Router"));
        }
        if(router)
        {
            _routerInfo = _instance->routerManager()->get(router);
            if(_routerInfo)
            {
                //
                // Make sure this router is not already registered with another adapter.
                //
                if(_routerInfo->getAdapter())
                {
                    throw AlreadyRegisteredException(__FILE__, __LINE__, "object adapter with router", 
                                                     _instance->identityToString(router->ice_getIdentity()));
                }

                //
                // Add the router's server proxy endpoints to this object
                // adapter.
                //
                vector<EndpointIPtr> endpoints = _routerInfo->getServerEndpoints();
                copy(endpoints.begin(), endpoints.end(), back_inserter(_routerEndpoints));
                sort(_routerEndpoints.begin(), _routerEndpoints.end()); // Must be sorted.
                _routerEndpoints.erase(unique(_routerEndpoints.begin(), _routerEndpoints.end()),
                                       _routerEndpoints.end());

                //
                // Associate this object adapter with the router. This way,
                // new outgoing connections to the router's client proxy will
                // use this object adapter for callbacks.
                //
                _routerInfo->setAdapter(this);

                //
                // Also modify all existing outgoing connections to the
                // router's client proxy to use this object adapter for
                // callbacks.
                //      
                _instance->outgoingConnectionFactory()->setRouterInfo(_routerInfo);
            }
        }
        else
        {
            //
            // Parse the endpoints, but don't store them in the adapter.
            // The connection factory might change it, for example, to
            // fill in the real port number.
            //
            vector<EndpointIPtr> endpoints;
            if(endpointInfo.empty())
            {
                endpoints = parseEndpoints(properties->getProperty(_name + ".Endpoints"));
            }
            else
            {
                endpoints = parseEndpoints(endpointInfo);
            }
            for(vector<EndpointIPtr>::iterator p = endpoints.begin(); p != endpoints.end(); ++p)
            {
                _incomingConnectionFactories.push_back(new IncomingConnectionFactory(instance, *p, this, _name));
            }
            if(endpoints.empty())
            {
                TraceLevelsPtr tl = _instance->traceLevels();
                if(tl->network >= 2)
                {
                    Trace out(_instance->initializationData().logger, tl->networkCat);
                    out << "created adapter `" << name << "' without endpoints";
                }
            }

            //
            // Parse published endpoints. If set, these are used in proxies
            // instead of the connection factory endpoints. 
            //
            string endpts = properties->getProperty(_name + ".PublishedEndpoints");
            _publishedEndpoints = parseEndpoints(endpts);
            if(_publishedEndpoints.empty())
            {
                transform(_incomingConnectionFactories.begin(), _incomingConnectionFactories.end(), 
                          back_inserter(_publishedEndpoints), Ice::constMemFun(&IncomingConnectionFactory::endpoint));
            }

            //
            // Filter out any endpoints that are not meant to be published.
            //
            _publishedEndpoints.erase(remove_if(_publishedEndpoints.begin(), _publishedEndpoints.end(),
                                      not1(Ice::constMemFun(&EndpointI::publish))), _publishedEndpoints.end());
        }

        if(!properties->getProperty(_name + ".Locator").empty())
        {
            setLocator(LocatorPrx::uncheckedCast(_instance->proxyFactory()->propertyToProxy(_name + ".Locator")));
        }
        else
        {
            setLocator(_instance->referenceFactory()->getDefaultLocator());
        }
    }
    catch(...)
    {
        destroy();
        __setNoDelete(false);
        throw;
    }
    __setNoDelete(false);  
}
Example #6
0
Ice::ObjectAdapter::ObjectAdapter(const InstancePtr& instance, const CommunicatorPtr& communicator,
                                  const ObjectAdapterFactoryPtr& objectAdapterFactory, 
                                  const string& name, const string& endpointInfo,
#ifdef ICEE_HAS_ROUTER
                                  const RouterPrx& router,
#endif
                                  bool noConfig) :
    _deactivated(false),
    _instance(instance),
    _communicator(communicator),
    _objectAdapterFactory(objectAdapterFactory),
    _servantManager(new ServantManager(instance, name)),
    _activateOneOffDone(false),
    _name(name),
#ifdef ICEE_HAS_LOCATOR
    _id(instance->initializationData().properties->getProperty(name + ".AdapterId")),
    _replicaGroupId(instance->initializationData().properties->getProperty(name + ".ReplicaGroupId")),
#endif
    _waitForActivate(false),
    _destroying(false),
    _destroyed(false),
    _noConfig(noConfig)
{
    if(_noConfig)
    {
        _reference = _instance->referenceFactory()->create("dummy -t", "");
        return;
    }

    PropertiesPtr properties = instance->initializationData().properties;

    //
    // Setup a reference to be used to get the default proxy options
    // when creating new proxies. By default, create twoway proxies.
    //
    string proxyOptions = properties->getPropertyWithDefault(_name + ".ProxyOptions", "-t");
    try
    {
        _reference = _instance->referenceFactory()->create("dummy " + proxyOptions, "");
    }
    catch(const ProxyParseException&)
    {
        InitializationException ex(__FILE__, __LINE__);
        ex.reason = "invalid proxy options `" + proxyOptions + "' for object adapter `" + _name + "'";
        throw ex;
    }

    __setNoDelete(true);
    try
    {
#ifdef ICEE_HAS_ROUTER
        if(!router)
        {
            string routerStr = _instance->initializationData().properties->getProperty(_name + ".Router");
            if(!routerStr.empty())
            {
                const_cast<RouterPrx&>(router) =
                    RouterPrx::uncheckedCast(_instance->proxyFactory()->stringToProxy(routerStr));
            }
        }
        if(router)
        {
            _routerInfo = _instance->routerManager()->get(router);
            if(_routerInfo)
            {
                //
                // Make sure this router is not already registered with another adapter.
                //
                if(_routerInfo->getAdapter())
                {
                    throw AlreadyRegisteredException(__FILE__, __LINE__, "object adapter with router",
                                                     _instance->identityToString(router->ice_getIdentity()));
                }

                //
                // Add the router's server proxy endpoints to this object
                // adapter.
                //
                vector<EndpointPtr> endpoints = _routerInfo->getServerEndpoints();
                copy(endpoints.begin(), endpoints.end(), back_inserter(_routerEndpoints));
                sort(_routerEndpoints.begin(), _routerEndpoints.end()); // Must be sorted.
                _routerEndpoints.erase(unique(_routerEndpoints.begin(), _routerEndpoints.end()),
                                       _routerEndpoints.end());

                //
                // Associate this object adapter with the router. This way,
                // new outgoing connections to the router's client proxy will
                // use this object adapter for callbacks.
                //
                _routerInfo->setAdapter(this);

                //
                // Also modify all existing outgoing connections to the
                // router's client proxy to use this object adapter for
                // callbacks.
                //      
                _instance->outgoingConnectionFactory()->setRouterInfo(_routerInfo);
            }
        }
        else
#endif
        {
            //
            // Parse the endpoints, but don't store them in the adapter.
            // The connection factory might change it, for example, to
            // fill in the real port number.
            //
            vector<EndpointPtr> endpoints;
            if(endpointInfo.empty())
            {
                endpoints = 
                    parseEndpoints(_instance->initializationData().properties->getProperty(_name + ".Endpoints"), true);
            }
            else
            {
                endpoints = parseEndpoints(endpointInfo, true);
            }

            for(vector<EndpointPtr>::iterator p = endpoints.begin(); p != endpoints.end(); ++p)
            {
                _incomingConnectionFactories.push_back(new IncomingConnectionFactory(_instance, *p, this));
            }

            if(endpoints.empty())
            {
                TraceLevelsPtr tl = _instance->traceLevels();
                if(tl->network >= 2)
                {
                    Trace out(_instance->initializationData().logger, tl->networkCat);
                    out << "created adapter `" << name << "' without endpoints";
                }
            }

            //
            // Parse published endpoints.
            //
            _publishedEndpoints = parsePublishedEndpoints();
        }

#ifdef ICEE_HAS_LOCATOR
        string locator = _instance->initializationData().properties->getProperty(_name + ".Locator");
        if(!locator.empty())
        {
            setLocator(LocatorPrx::uncheckedCast(_instance->proxyFactory()->stringToProxy(locator)));
        }
        else
        {
            setLocator(_instance->referenceFactory()->getDefaultLocator());
        }
#endif
    }
    catch(...)
    {
        //
        // There's no need to remove the adapter from the factory if
        // creation fails. Furthermore, since this code is called with
        // the factory mutex locked, we can't call removeObjectAdapter
        // on the factory here so we clear the factory reference to
        // ensure it won't be called by destroy().
        // 
        _objectAdapterFactory = 0;

        destroy();
        __setNoDelete(false);
        throw;
    }
    __setNoDelete(false);  
}