Today is...
Friday, October 20, 2017
The OPC Community Forum.
Removing Groups Using OPC RemovGroup Call
Using OPC RemoveGroup call blocked though items are removed from groups.

Hi,

We have our own OPCclient developed using OPC Foundation C++ SDK.
I am able to connect to Matrikon simulation server and add multiple groups and items to each group. Data exchange also working fine.

During disconnect when I tried to remove the groups using RemoveGroup
call. I am not receiving any response and thread is waiting for a response from the API.

I am following below steps for disconnection.


ipGrpStMgt->Release();
ipCP->Unadvise(dwAdvice);
ipCP->Release();
ipCallback->Release();
ipGroup->Release();
m_ipServer->RemoveGroup(hGroup, FALSE);

Please correct me if missed something. I am trying hard on this since last 15-20 days.

Thanks,
Kiran

The server might be blocked releasing the connection point object in your client while your client is blocked on the server waiting for the RemoveGroup() call to be processed.

I would try moving the given cleanup code into a secondary thread, while the main thread executes the standard Windows message loop (GetMessage/TranslateMessage/DispatchMessage) until the secondary thread completes. Maybe add some trace to the connection point object to track is releases.


> ipGrpStMgt->Release();
> ipCP->Unadvise(dwAdvice);
> ipCP->Release();
> ipCallback->Release();
> ipGroup->Release();
> m_ipServer->RemoveGroup(hGroup, FALSE);

Hi ,

Thanks for the response .

The cleanup code is in a different thread and data exchange is in another thread. I will try adding some debugs in connection point
object to track

Kiran

> The server might be blocked releasing the connection point
> object in your client while your client is blocked on the
> server waiting for the RemoveGroup() call to be processed.

> I would try moving the given cleanup code into a secondary
> thread, while the main thread executes the standard Windows
> message loop (GetMessage/TranslateMessage/DispatchMessage)
> until the secondary thread completes. Maybe add some trace
> to the connection point object to track is releases.

When building the client under debug, check the return code from the group object's release call. If the final release is not equal to zero (reference count), perhaps there are some references to the group object still being held by the client when the RemoveGroup() call is being done.

You definitely want all references to the group by the client to have been released at the point RemoveGroup() has been called.

Hi,

Thanks for your inputs. When I checked the status after group release call, for the 1st group itself I am getting reference value as 0.

I have 2 groups added to server. So when I loop through the groups as shown below the unadvise call is blocking for the 2nd group.

Below I am sharing skeleton code. Please correct me if I am missing something.


std::map<HANDLE,group_info_st>::iterator git;
std::map<OPCHANDLE, server_item_st>::iterator item;

DWORD pRevisedUpdateRate,status;

item = m_item_info.begin();

git = m_grp_info.begin();

while(git!=m_grp_info.end()){
/* Deactivating group before removing the items */
hRes = git->second.pGrpStMgt->SetState(NULL,&pRevisedUpdateRate,FALSE,NULL,NULL,NULL,NULL);
/* Remove items */
hRes = git->second.pGroup->RemoveItems(item->second.itemcount,item->second.m_pItems,&pErrors);
git->second.pGrpStMgt->Release();
Note : In second iteration call is blocking here ...
hRes = git->second.pCP->Unadvise(git->second.dwAdvice);
git->second.pCP->Release();
git->second.pCallback->Release();
status = git->second.pGroup->Release();
Note: for first group release it self status here is coming as 0
git++;
}

After this I am removing groups as shown below ...

git = m_grp_info.begin();
while(git!=m_grp_info.end()){
if(git->second.pGroup){
hRes = m_ipServer->RemoveGroup(git->second.hGroup,FALSE);
}

git++;
}

          Note : In second iteration call is blocking here ... 
> hRes = git->second.pCP->Unadvise(git->second.dwAdvice);
> git->second.pCP->Release();
> git->second.pCallback->Release();
> status = git->second.pGroup->Release();

This blocking location again indicates the possibility that the client is not processing the server's COM calls to the callback object that resides in the client. When the Unadvise() is called on the server, the server calls Release() on the client's callback object. To see this, add trace within the Release() and destructor of the callback object.

So, again I recommend creating and/or verifying that a thread that is initialized for COM is actively executing the Windows message pump while the cleanup thread is blocked.

Hi,

Today I observed a different scenario.

I did the test on a different setup where I have 2 groups with 2 items in one group and ~500 items in other group. On this setup, to my surprise functionality is working fine and groups are getting removed.

On the setup where I have ~5000 items with 2 groups it is failing.

Thanks,
Kiran

Hi,

Till today no clue on why the call is blocking. I tried all the possible scenarios. Just to update the remove group call is blocking when there are ~ 1000 items defined.

Thanks,
Kiran

Hello,

I am not sure this would solve the issue.
I would first set the group to inactive, then remove the items and then remove the group.

My2c.

Good luck,

Mark
http://www.peakhmi.com/

Hi Mark,

Thanks for the response . I tried what you have suggested below .

But no luck :-( .

> I am not sure this would solve the issue.
> I would first set the group to inactive, then remove the items and then
> remove the group.

Thanks,
Kiran