Archived

This forum has been archived. Please start a new discussion on GitHub.

i puzzle about the example bidirS!

in bidirs ,the addclient method works well.
my code is very similar to the bidirS's code
but my code can't work well as the example
the function 'addClient' will be stopped by the
IceUtil::Monitor<IceUtil::RecMutex>::Lock lock( *this );
i don't know the reason.
it looks like the addclient and run have a common recmutex.
but why the example can work well ?


these are my code ,
void NetControlI::run()
{
//if i delete the code "IceUtil::Monitor<IceUtil::RecMutex>::Lock lock( *this );"
// function addClient can get the recmutex

IceUtil::Monitor<IceUtil::RecMutex>::Lock lock( *this );
CMessage mesSendToClient;
while( !bDestroy )
{
mesSendToClient = refMQFromParse.getMessage();
if( mesSendToClient.iId == -1 )
{
if( mesSendToClient.sMessage == "quit" )
break;
}
try
{
if( isUsedLinkId[ mesSendToClient.iId ] )
ClientPrx[ mesSendToClient.iId ] -> sendMessage( mesSendToClient.sMessage );
}
catch( const Exception& ex )
{
isUsedLinkId[ mesSendToClient.iId ] = false;
ClientPrx[ mesSendToClient.iId ] = NULL;
cerr << ex << endl;
}
}

}
::Ice::Int NetControlI::addClient( const Ice::Identity &a , const Ice::Current &b )
{
//my code can't get the recmutex , if there is a same code in function run.
IceUtil::Monitor<IceUtil::RecMutex>::Lock lock(*this);
SendToClientPrx client = SendToClientPrx::uncheckedCast( b.con->createProxy(a)->ice_oneway()->ice_timeout(-1)->ice_secure(false));

for( int i = 0 ; i < iMaxLink ; ++i )
{
if( !isUsedLinkId )
{
isUsedLinkId = true;
ClientPrx = client;
return i;
}
}
}



//refMQFromParse is a object of CMessageQueue
void CMessageQueue::putMessage( const CMessage &a )
{
IceUtil::Monitor< IceUtil::Mutex >::Lock lock( *this );
if(MessageQueue.empty() )
notify();
MessageQueue.push( a );

}
CMessage CMessageQueue::getMessage()
{
IceUtil::Monitor< IceUtil::Mutex >::Lock lock( *this );

while( MessageQueue.empty() )
wait();

CMessage sTemp = MessageQueue.front();
MessageQueue.pop();

return sTemp;
}

Comments

  • bernard
    bernard Jupiter, FL
    IceUtil::Monitor<IceUtil::RecMutex>::Lock lock( *this );

    This line means "acquire a Monitor/RecMutex named *this, and release it in the destructor of lock".

    Obviously, if one thread acquires this mutex and enters an infinite loop ( while( !bDestroy ) ), no other thread will be able to acquire this mutex.

    In the bidir demo (CallbackI.cpp), the answer is the
    timedWait(IceUtil::Time::seconds(2));
    in the loop.
    This releases the *this mutex for 2 seconds (or until notify is called).

    Cheers,
    Bernard
  • if i let "run" wait 1 second , enabling "addclient" to get recmutex,
    but "addclient" can't finish in 1 second .
    "run" will wait until " addclient " release the recmutex ?
  • matthew
    matthew NL, Canada
    fw_csha wrote:
    if i let "run" wait 1 second , enabling "addclient" to get recmutex,
    but "addclient" can't finish in 1 second .
    "run" will wait until " addclient " release the recmutex ?

    Yes, being a mutex it cannot be acquired by two threads at the same time.

    As I previously recommended to you you should read a good book or tutorial on monitors and MT programming. Here is a link to one that is provided by Sun on the Java monitor which is the same concept as the IceUtil Monitor class. http://java.sun.com/docs/books/tutorial/essential/threads/monitors.html.

    Regards, Matthew