Home Help Center

Asynchronous - AMI and AMD

mohdiarramohdiarra Member Mohamed DiarraOrganization: Continental Airlines, IncProject: CLS
Hi,
I'm trying to have a server send data to multiple clients asynchrounously.
I followed the example in the Ice 3.1.0.pdf file for Asynchronous Programming and the code compiles fines.
I am able to have it run and it works for the first call when a client sends a request to the server, the server sends that data to all the clients connected.
But when I try to do the same thing again a second time I get a runtime error with the server with this output on the server window:

Assertion failed: _currentWriteEncaps, file c:\src\vc80\stage\Ice-3.1.0\include\
Ice/BasicStream.h, line 168

and this happens when the server it sending the data to the clients:
for (unsigned i = 0; i < m_sendUpdateJobs.size(); i++)
{
IceUtil::Mutex::Lock sync(*this);
m_sendUpdateJobs->execute(newUpdate);
}

I have done a lot of search but couldn't find anything that could help me with this error.
I really don't know what to do to fix this. Please help me.

Comments

  • marcmarc FloridaAdministrators, ZeroC Staff Marc LaukienOrganization: ZeroC, Inc.Project: The Internet Communications Engine ZeroC Staff
    Welcome to our forums. Please see this post regarding our support policy, and update your signature.

    Also, please include more details about your application. What operating system are you using, what compiler, which version? Do you have a small, but complete, self-contained example that demonstrates the problem?
  • mohdiarramohdiarra Member Mohamed DiarraOrganization: Continental Airlines, IncProject: CLS
    I'm using Microsoft Visual Studio 2005 (VC8) with Windows XP Pro SP2.
    I'm attaching my project.
    thanks in advance
  • marcmarc FloridaAdministrators, ZeroC Staff Marc LaukienOrganization: ZeroC, Inc.Project: The Internet Communications Engine ZeroC Staff
    Your application is not thread-safe. You do not mutex-protect m_jobs properly:
    for (unsigned i = 0; i < m_jobs.size(); i++)
        {
            IceUtil::Mutex::Lock sync(*this);
            m_jobs[i]->execute(newUpdate);
        }
    

    This is not safe because sendUpdate_async() might modify m_jobs while the for-loop is running. You must move the mutex lock outside the for-loop, so that m_jobs is protected. As an alternative, make a temporary copy of m_jobs (with proper mutex protection when copying), and then iterate over the copy. This way, you can achieve a higher level of concurrency.

    You should also verify if you do not also need mutex protection for m_clientID.
  • mohdiarramohdiarra Member Mohamed DiarraOrganization: Continental Airlines, IncProject: CLS
    hi,
    thanks for the fast reply.

    I have tried this code:
    IceUtil::Mutex::Lock sync(*this);
    std::vector<sendUpdateJobPtr>::const_iterator p;
    for(p = m_jobs.begin(); p != m_jobs.end(); ++p)
    (*p)->execute(newUpdate);
    and this one also as you suggested:
    IceUtil::Mutex::Lock sync(*this);
    std::vector<sendUpdateJobPtr> newJobs;
    for(p = m_jobs.begin(); p != m_jobs.end(); ++p)
    newJobs.push_back(*p);

    for(p = newJobs.begin(); p != newJobs.end(); ++p)
    (*p)->execute(newUpdate);
    and they both do the same thing as before, when a first request is made by a client, the server updates all the clients. But when a second one is made, that's when the runtime error occurs...
  • marcmarc FloridaAdministrators, ZeroC Staff Marc LaukienOrganization: ZeroC, Inc.Project: The Internet Communications Engine ZeroC Staff
    I just realized that you do not clear m_jobs after your loop. This means that subsequent calls to requestUpdate() will call AMD callback objects for already finished requests again, which leads to the failure.
  • mohdiarramohdiarra Member Mohamed DiarraOrganization: Continental Airlines, IncProject: CLS
    But by clearing m_jobs I all the clients data in there so I can't send the data to anybody because m_jobs will be empty.
    I don't know if there is a better way to do this, but I'm basically trying to have the server get some data from a client and send that same data to everybody connected.
    Thank you very much for all your help.
  • marcmarc FloridaAdministrators, ZeroC Staff Marc LaukienOrganization: ZeroC, Inc.Project: The Internet Communications Engine ZeroC Staff
    You should do this with callbacks or with IceStorm. Just like for regular calls, there must be exactly one response for every AMD request. AMD doesn't change the semantics of Ice operation calls, it only offers an alternative implementation technique.
  • mohdiarramohdiarra Member Mohamed DiarraOrganization: Continental Airlines, IncProject: CLS
    Thank you very much, I thought that I could do this using AMD.
    I'm going to check out IceStorm and see what I can do with it.
    Thanks again, I should have done this a long time ago, I've been searching for a way to do this for about a week. :)
  • mohdiarramohdiarra Member Mohamed DiarraOrganization: Continental Airlines, IncProject: CLS
    Hi,
    I'm trying to write a multiplayer game where multiple players will connect to one server which will update everybody when an action is performed by one player.
    Do you have any suggestion of how I might do this using ICE ???
    I got the connecting to work but I can't figure out a way to have the server update everybody asynchronously.
    Thank you very much for your help.
  • marcmarc FloridaAdministrators, ZeroC Staff Marc LaukienOrganization: ZeroC, Inc.Project: The Internet Communications Engine ZeroC Staff
    There are many possibilities to do this. I'm afraid providing help with the design of such an application is out of the scope of the support we can provide here in these forums.

    My recommendation would be to read all the articles in Connections, including the articles about our chat server example.
Sign In or Register to comment.