Esempio n. 1
0
void
Slice::writeEndCode(Output& out, const ParamDeclList& params, const OperationPtr& op, bool prepend)
{
    string prefix = prepend ? paramPrefix : "";
    for(ParamDeclList::const_iterator p = params.begin(); p != params.end(); ++p)
    {
        writeParamEndCode(out, (*p)->type(), (*p)->optional(), fixKwd(prefix + (*p)->name()), (*p)->getMetaData());
    }
    if(op && op->returnType())
    {
        writeParamEndCode(out, op->returnType(), op->returnIsOptional(), "__ret", op->getMetaData());
    }
}
Esempio n. 2
0
void
Slice::writeAllocateCode(Output& out, const ParamDeclList& params, const OperationPtr& op, bool prepend, int typeCtx, bool cpp11)
{
    string prefix = prepend ? paramPrefix : "";
    for(ParamDeclList::const_iterator p = params.begin(); p != params.end(); ++p)
    {
        writeParamAllocateCode(out, (*p)->type(), (*p)->optional(), fixKwd(prefix + (*p)->name()), (*p)->getMetaData(),
                               typeCtx, cpp11, getEndArg((*p)->type(),(*p)->getMetaData(), (*p)->name()) != (*p)->name());
    }
    if(op && op->returnType())
    {
        writeParamAllocateCode(out, op->returnType(), op->returnIsOptional(), "__ret", op->getMetaData(), typeCtx, cpp11,
                               getEndArg(op->returnType(), op->getMetaData(), "__ret") != "__ret");
    }
}
Esempio n. 3
0
void
Slice::ObjCGenerator::MetaDataVisitor::visitOperation(const OperationPtr& p)
{
    if(p->hasMetaData("UserException"))
    {
        ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container());
        if(!cl->isLocal())
        {
            ostringstream os;
            os << "ignoring invalid metadata `UserException': directive applies only to local operations "
               << ": warning: metadata directive `UserException' applies only to local operations "
               << "but enclosing " << (cl->isInterface() ? "interface" : "class") << "`" << cl->name()
               << "' is not local";
            emitWarning(p->file(), p->line(), os.str());
        }
    }
    validate(p);
}
void SyncManagerImpl::OnSyncChangeReceived(const NetworkConnectionPtr& connection, NetworkInMessage& msg)
{
#if defined(SYNC_DEBUG)
	LogInfo("%s ReceivedSyncPacket", m_syncContext->GetLocalUser()->GetName().GetString().c_str());
#endif

	size_t connectionIndex;
	if (GetIndexOfConnection(connection, connectionIndex))
	{
		RemoteSyncPeer& remotePeer = m_remoteHosts[connectionIndex];

		if (XTVERIFY(remotePeer.m_bHandshakeComplete))
		{
			XTASSERT(remotePeer.m_systemID != kUnknownSystemID);

			// Read out the number of ops sent in this message
			int32 numOps = msg.ReadInt32();

			// Read out each of the ops
			for (int32 i = 0; i < numOps; ++i)
			{
				VersionedOp incomingVersionedOp;

				// Read the state that the remote machine was in before the op was applied
				incomingVersionedOp.m_state.m_opsSent = msg.ReadInt32();
				incomingVersionedOp.m_state.m_opsReceived = msg.ReadInt32();

				// Read the type of the op
				Operation::Type opType = (Operation::Type)msg.ReadByte();

				// Create an op of the appropriate type
				OperationPtr incomingOp = m_syncContext->GetOpFactory().Make(opType, remotePeer.m_authorityLevel);

				// Read the op data
				incomingOp->Deserialize(msg);

				incomingVersionedOp.m_op = incomingOp;

				// Add it to the list of incoming ops
				remotePeer.m_incoming.push_back(incomingVersionedOp);
			}
		}
	}
}
Esempio n. 5
0
std::string Server::handleQuery(const std::string& query)
{
  std::cout << "PARSING QUERY: " << query << std::endl;
  OperationPtr operation = parseQuery(query);
  if(operation.get() == NULL)
    return Linda::Messages::INVALID_MESSAGE;
  
  ParserToDatabaseProxy answerHandler(db);
  answerHandler.handleOperation(operation);
  if(answerHandler.shouldLastOperationWait())
  {
    lastTimeout_ = answerHandler.getLastOperationTimeout();
    return Linda::Messages::TIMEOUT_MESSAGE;
  }
  else
    if(answerHandler.hasLastOperationAddedElement())
      handleWaitingQueue();
    return answerHandler.getLastOperationAnswer();
}
Esempio n. 6
0
string CodeGenerator::generateJSServerImp(const NamespacePtr &nPtr, const InterfacePtr &pPtr, const OperationPtr &oPtr)
{
    ostringstream str;
    str << nPtr->getId() << "." << pPtr->getId() << "Imp.prototype." << oPtr->getId() << " = function (current";

    vector<ParamDeclPtr> & vParamDecl = oPtr->getAllParamDeclPtr();
    for (size_t i = 0; i < vParamDecl.size(); i++)
    {
        str << ", " << vParamDecl[i]->getTypeIdPtr()->getId();
    }

    str << ") {" << endl;
    INC_TAB;
    str << TAB << "//TODO::" << endl;
    DEL_TAB;
    str << "};" << endl << endl;

    return str.str();
}
Esempio n. 7
0
string
Slice::classDefToDelegateString(const ClassDefPtr& cl, int typeCtx, bool cpp11)
{
    assert(cl->isDelegate());

    // A delegate only has one operation
    OperationPtr op = cl->allOperations().front();

    TypePtr ret = op->returnType();
    string retS = returnTypeToString(ret, op->returnIsOptional(), op->getMetaData(), typeCtx, cpp11);

    string t = "::std::function<" + retS + " (";

    if(cpp11)
    {
        // inputTypeToString usually passes local operation values by
        // reference. This is not the desired behavior for delegates
        typeCtx &= ~TypeContextLocalOperation;
        typeCtx |= TypeContextDelegate;
    }

    ParamDeclList paramList = cl->allOperations().front()->parameters();
    for(ParamDeclList::iterator q = paramList.begin(); q != paramList.end(); ++q)
    {
        if((*q)->isOutParam())
        {
            t += outputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), typeCtx, cpp11);
        }
        else
        {
            t += inputTypeToString((*q)->type(), (*q)->optional(), (*q)->getMetaData(), typeCtx, cpp11);
        }

        t += distance(q, paramList.end()) == 1  ? "" : ", ";
    }

    t += ")>";

    return t;
}
Esempio n. 8
0
string
Slice::opFormatTypeToString(const OperationPtr& op)
{
    switch(op->format())
    {
    case DefaultFormat:
        return "::Ice::DefaultFormat";
    case CompactFormat:
        return "::Ice::CompactFormat";
    case SlicedFormat:
        return "::Ice::SlicedFormat";

    default:
        assert(false);
    }

    return "???";
}
void SyncManagerImpl::Update()
{
	PROFILE_SCOPE("SyncManager Update");

	const OperationList& appliedOpList = m_syncContext->GetAppliedOperations();

	// Add all the locally applied changes to the outgoing queue of the remote peers
	if (!appliedOpList.empty())
	{
		for (size_t i = 0; i < appliedOpList.size(); ++i)
		{
			for (size_t j = 0; j < m_remoteHosts.size(); ++j)
			{
				RemoteSyncPeer& currentHost = m_remoteHosts[j];

				if (currentHost.m_bHandshakeComplete && currentHost.m_bHasAddedStartingState)
				{
					currentHost.SendOp(appliedOpList[i]);
				}
			}
		}

		// Clear out the list of locally applied operations
		m_syncContext->ClearAppliedOperations();
	}


	// Check to see if any new remote peers have connected since the last sync, and if so
	// add create operation for each element in our list to their outgoing queue
	for (size_t hostIndex = 0; hostIndex < m_remoteHosts.size(); ++hostIndex)
	{
		RemoteSyncPeer& currentHost = m_remoteHosts[hostIndex];

		if (currentHost.m_bHandshakeComplete && !currentHost.m_bHasAddedStartingState)
		{
#if defined(SYNC_DEBUG)
			LogInfo("%s Sending Deltas", m_syncContext->GetLocalUser()->GetName().GetString().c_str());
#endif
			// Check that the deltas are the first ops we are sending to the remote client
			XTASSERT(currentHost.m_localState.m_opsSent == 0);
			XTASSERT(currentHost.m_outgoing.empty());
			XTASSERT(currentHost.m_sendList.empty());

			AddCreateOpForElementRecurs(currentHost, m_syncContext->GetRootObject());
			currentHost.m_bHasAddedStartingState = true;
		}
	}

	
	const TransformManager& transfromMgr = m_syncContext->GetTransformManager();

	// Loop through all the incoming remote changes
	for (size_t hostIndex = 0; hostIndex < m_remoteHosts.size(); ++hostIndex)
	{
		RemoteSyncPeer& currentHost = m_remoteHosts[hostIndex];

		if (currentHost.m_bHandshakeComplete)
		{
			VersionedOpList& incomingOpList = currentHost.m_incoming;
			VersionedOpList& outgoingOpList = currentHost.m_outgoing;

			// For each incoming operation
			for (VersionedOpList::iterator opIt = incomingOpList.begin(); opIt != incomingOpList.end(); ++opIt)
			{
				VersionedOp& remoteMsg = *opIt;

				// Debugging hack
				if (remoteMsg.m_state.m_opsSent == 0)
				{
					// The first op we get should be a catch-up data create of the root
					XTASSERT(remoteMsg.m_op->GetType() == Operation::Create && remoteMsg.m_op->GetTargetGuid() == m_syncContext->GetRootObject()->GetGUID());
				}

#if defined(SYNC_DEBUG)
				LogInfo("%s received op (%s) from %s, version %i %i", m_syncContext->GetLocalUser()->GetName().GetString().c_str(), remoteMsg.m_op->GetOpDescription().c_str(), currentHost.m_userName.c_str(), remoteMsg.m_state.m_opsSent, remoteMsg.m_state.m_opsReceived);	
#endif

				// Discard the acknowledged operations, we don't need to transform against them anymore
				while (!outgoingOpList.empty() && outgoingOpList.front().m_state.m_opsSent < remoteMsg.m_state.m_opsReceived)
				{
#if defined(SYNC_DEBUG)
					LogInfo("  Invalidating %s op, version %i %i", outgoingOpList.front().m_op->GetTypeName(), outgoingOpList.front().m_state.m_opsSent, outgoingOpList.front().m_state.m_opsReceived);
#endif
					outgoingOpList.erase(outgoingOpList.begin());
				}

				if (remoteMsg.m_op->GetType() != Operation::Ack)
				{
					// Ensure that our starting state is the same as the one the message was sent from
					XTASSERT(remoteMsg.m_state.m_opsSent == currentHost.m_localState.m_opsReceived);

					// Transform the incoming ops by the changes that have not yet been acknowledged by the remote host
					for (VersionedOpList::iterator outgoingOpIt = outgoingOpList.begin(); outgoingOpIt != outgoingOpList.end(); ++outgoingOpIt)
					{
						VersionedOp& localMsg = *outgoingOpIt;

						TransformedPair transformResult = transfromMgr.Transform(localMsg.m_op, remoteMsg.m_op);

						localMsg.m_op = transformResult.m_localOpTransformed;
						remoteMsg.m_op = transformResult.m_remoteOpTransformed;

						// Early-out of the loop if the op was rendered invalid by the transformation
						if (remoteMsg.m_op->GetType() == Operation::Noop)
						{
							break;
						}
					}

					if (remoteMsg.m_op->GetType() != Operation::Noop)
					{
						// Const-cast so that we can apply the operation and change the auth level.  
						// All the rest of the code uses const for safety, as the ops should not change except when applied
						OperationPtr clonedOp = const_cast<Operation*>(remoteMsg.m_op.get());

						// Apply the transformed ops to the local data set
						clonedOp->Apply(m_syncContext);

						// Now that the op has been applied locally, it is set to the local system's authority level before
						// being queued to be passed to the other systems
						clonedOp->SetAuthorityLevel(m_syncContext->GetAuthorityLevel());

						// Add the op to the list of changes applied this Sync so that we can notify the listeners when all changes have been applied
						m_pendingNotifications.push(clonedOp);

						// Add the transformed op to the outgoing list for the other hosts
						for (size_t otherHostIndex = 0; otherHostIndex < m_remoteHosts.size(); ++otherHostIndex)
						{
							if (otherHostIndex != hostIndex)
							{
								RemoteSyncPeer& otherHost = m_remoteHosts[otherHostIndex];
								if (otherHost.m_bHandshakeComplete && otherHost.m_bHasAddedStartingState)
								{
									otherHost.SendOp(clonedOp);
								}
							}
						}
					}

					++currentHost.m_localState.m_opsReceived;
				}

				// Record what we know of the state of the remote machine
				currentHost.m_remoteState = remoteMsg.m_state;
			}

			incomingOpList.clear();
		}
	}

	// Send the changes in each remotePeer's outgoing op list.  
	// Nothing will be sent if the last message was not acknowledged.  
	for (size_t hostIndex = 0; hostIndex < m_remoteHosts.size(); ++hostIndex)
	{
		SendSyncMessage(m_remoteHosts[hostIndex]);
	}

	// Notify listeners about the remote changes
	if (!m_pendingNotifications.empty())
	{
		if (m_listener)
		{
			try
			{
				m_listener->OnSyncChangesBegin();
			}
			catch (...)
			{
				LogError("Exception occurred during OnSyncChangesBegin callback");
			}
		}

		while (!m_pendingNotifications.empty())
		{
			OperationPtr currentOp = m_pendingNotifications.front();

			try
			{
				currentOp->Notify(m_syncContext);
			}
			catch (...)
			{
				LogError("Exception occurred during Sync notification callback");
			}

			m_pendingNotifications.pop();
		}

		if (m_listener)
		{
			try
			{
				m_listener->OnSyncChangesEnd();
			}
			catch (...)
			{
				LogError("Exception occurred during OnSyncChangesEnd callback");
			}
		}
	}
}