Re: How to delete servants?

szyk100 szyk100 at o2.pl
Thu Dec 10 18:53:50 GMT 2015


Hi

[[ current state ]]
Now I still try to write "chat" server and client using Corba. I have problem with memory management. Now I have little progress because servant UserImp (client side created) is deleted as expected. But problem is still with proxy class RoomControllerImp (server side created). mRoomController is RoomControllerImp variable in UserImp class. It is used as proxy between UserImp and RoomImp (server side factory for both users and controllers). I have read about _ptr and _var but still I feel uncomfortable with them.

[[ questions about _var and _ptr ]]
1. Why can't I return _var from function? I must alvays return _ptr.
2. Is it safe to send _var to function as argument/parameter?
3. Why don't I need call CORBA::release when I get _ptr as argumrnt/parameter?

[[ RoomController life cycle ]]
Now I show step by step how I create, use and delete RoomControllerImp

1. Creation
void WinMainC::connectToServer()
{
    if(!mUser)
    {
        mUser = new UserImp();
        connect(mUser, &UserImp::newMessage, this, &WinMainC::showMessage);
        connect(mUser, &UserImp::sigAddUser, this, &WinMainC::addUser);
        connect(mUser, &UserImp::sigDelUser, this, &WinMainC::delUser);
    }
    mUser->mName = QString("Szyk%1").arg(qrand());
    mUser->mPassword = "pass";
    mUser->mUserObjectID = mPoa->activate_object(mUser);
    TCzat::User_var lUserPtr = mUser->_this();
    mUser->mRoomController = mRoom->joinUser(lUserPtr);
    //CORBA::release(lUserPtr);
}

WinMainC is client side Qt QMainWindow descendant.
As you can se RoomController is created by RoomImp::joinUser:

TCzat::RoomController_ptr RoomImp::joinUser(::TCzat::User_ptr aUser)
{
    // add user to internal list
    mUsers.append(::TCzat::User::_duplicate(aUser));

    // call all users to add user to they list
    for(int i = 0; i < mUsers.length(); ++i)
        mUsers[i]->addUser(::TCzat::User::_duplicate(aUser));

    Room_var lRoom = _this();
    RoomControllerImp* lController = new RoomControllerImp(TCzat::Room::_duplicate(lRoom), mPoa);
    PortableServer::ObjectId_var lControllerID = mPoa->activate_object(lController);
    //mRoomControllers.append(lControllerID);

    RoomController_ptr lControllerPtr = lController->_this();
    return lControllerPtr;
}


2. Usage of RoomControllerImp:

When user hits Return key in QTextLine widget this function is called:

void WinMainC::returnPressed()
{
    mUser->sendMessage(CORBA::wstring_dup(mUser->mName.toStdWString().c_str()), CORBA::wstring_dup(mRoom->name()), CORBA::wstring_dup(ui->mMessage->text().toStdWString().c_str()));

    ui->mMessage->setText("");
}

Following functions are called in order to perform message broadcast:

void UserImp::sendMessage(const ::CORBA::WChar* aFrom, const ::CORBA::WChar* aTo, const ::CORBA::WChar* aMessage)
{
    mRoomController->message(CORBA::wstring_dup(aFrom), CORBA::wstring_dup(aTo), CORBA::wstring_dup(aMessage));
}

void RoomControllerImp::message(const ::CORBA::WChar* aFrom, const ::CORBA::WChar* aTo, const ::CORBA::WChar* aMessage)
{
    mRoom->message(CORBA::wstring_dup(aFrom), CORBA::wstring_dup(aTo), CORBA::wstring_dup(aMessage));
}


3. Delete RoomControllerImp
When main window is deleted its destructor is called. It try delete PortableServer::Servant_var<UserImp> mUser; variable.

WinMainC::~WinMainC()
{
    cout << "WinMainC delete begin" << endl << flush;
    delete ui;

    mUser->destroy();
    mPoa->deactivate_object(mUser->mUserObjectID);

    cout << "WinMainC delete end" << endl << flush;
}

UserImp::mRoomController is TCzat::RoomController_ptr, so I call CORBA::release() in next function.

void UserImp::destroy()
{
    TCzat::User_var lUserPtr = _this();
    mRoomController->removeUser(lUserPtr);
    mRoomController->destroy();
    CORBA::release(mRoomController);
}

void RoomControllerImp::removeUser(::TCzat::User_ptr aUser)
{
    mRoom->removeUser(aUser);
}

void RoomImp::removeUser(::TCzat::User_ptr aUser)
{
    // remove user from internal list
    for(int i = 0; i < mUsers.size();)
        if(QString::fromStdWString(wstring(mUsers[i]->name())) == QString::fromStdWString(wstring(aUser->name())))
            mUsers.removeAt(i);
        else
            ++i;

    // call all users to remove user from they list
    for(int i = 0; i < mUsers.length(); ++i)
        mUsers[i]->delUser(::TCzat::User::_duplicate(aUser));
}

void RoomControllerImp::destroy()
{
    PortableServer::ObjectId_var lId = mPoa->servant_to_id(this);
    mPoa->deactivate_object(lId);
}



thanks and regards
Szyk Cech




More information about the omniORB-list mailing list