COFE collapses when using CoUninitialize in destruction

Discusses use of COCO, the process simulation and modelling software suite from AmsterCHEM, downloadable from http://www.cocosimulator.org

Moderator: jasper

Post Reply
bcbooo
Posts: 66
Joined: 22 November 2012, 06:41
Location: China

COFE collapses when using CoUninitialize in destruction

Post by bcbooo »

I have finished a simple Unit Operation, it performs very good in the environment of Aspen Plus, but easily collapses in the environment of COFE.

The following is episode of my code:

Code: Select all

// some construction code
SampleUnitOperation :: SampleUnitOperation
{
CoInitialize(NULL);
// have defined CComPtr<IThermoCompound> tc;
HRESULT hr=tc.CoCreateInstance(clsid);
}

Code: Select all

//some destruction code
SampleUnitOperation :: ~SampleUnitOperation
{
tc=NULL;
CoUninitialize();
}
Well, there's no error with the code, but after the process finished in the COFE, COFE will collapse at this case:

click "Solve", then click "Reset", then click "Solve", then click "Reset", then again "Solve". At this moment, COFE will appear this window:(at the attachment)

Then I tested the COFE, I find when click "Solve", the COFE will call the construction function "SampleUnitOperation :: SampleUnitOperation" twice. But Aspen Plus only calls this construction function at the first time when inserts this Unit Operation, not at the "Solve" function.

So the collapsion of COFE is the conflict of construction function and destruction function, COFE's twice calling on "Solve" results in the chaos of COM reference.

So, why does COFE call Unit Operation's construction function at the "Slove" command twice? It's rational to call construction at the Unit Operation's creation, not the "Solve".

And where should I release the "tc" COM pointer and call "CoUninitialize"?

Thank you Jasper, any response will be appreciated.
Attachments
error window
error window
Untitled.jpg (232.15 KiB) Viewed 27907 times
User avatar
jasper
Posts: 1129
Joined: 24 October 2012, 15:33
Location: Spain
Contact:

Re: COFE collapses when using CoUninitialize in destruction

Post by jasper »

There are two things of your mail rather unclear to me:

1) why would a PMC call CoInitialize and CoUninitialize? I presume your unit operation is a CAPE-OPEN COM object, so the COM initialization is already done by the PME that created your unit operation. What is your point of re-initializing COM?

2) why would a unit operation create an object that implements ICapeThermoCompounds?
User avatar
jasper
Posts: 1129
Joined: 24 October 2012, 15:33
Location: Spain
Contact:

Re: COFE collapses when using CoUninitialize in destruction

Post by jasper »

To answer your question about the second CoCreateInstance: by default COFE does not solve in the main thread. It solves in a background thread. As COFE uses the apartment threaded model, it cannot use the unit operations from the main thread in the solution thread. Therefore, it saves the one in the main thread, creates a new one in the solution thread, and restores it from the saved one. Now there are two copies; one in the main thread and one in the solution thread.

You can turn this off (in preferences you can untick the box to use a separate thread for solutions) but now solving is done in the main thread, which makes the application respond less. More-over, this is the calling pattern to be expected in any multi-threaded CAPE-OPEN application. See here for more info:

http://cocosimulator.org/down.php?dl=AI ... _notes.pdf
bcbooo
Posts: 66
Joined: 22 November 2012, 06:41
Location: China

Re: COFE collapses when using CoUninitialize in destruction

Post by bcbooo »

Sorry Jasper, it's my fault to re-initialize COM. And I don't implement ICapeThermoCompounds at there, it's just a sample.

But there are still errors. My code is modified as the following:

Code: Select all

SampleUnitOperation :: SampleUnitOperation
{
// have defined CComPtr<ISample> tc;
HRESULT hr=tc.CoCreateInstance(clsid);
}

SampleUnitOperation :: ~SampleUnitOperation
{
tc=NULL;
}
If I called "tc=NULL" in the destruction, the collapsion still occurs. I don't know why.
User avatar
jasper
Posts: 1129
Joined: 24 October 2012, 15:33
Location: Spain
Contact:

Re: COFE collapses when using CoUninitialize in destruction

Post by jasper »

Is tc a shared resource (e.g. a global variable, or a static variable)? How is it declared?

If there is only one copy of tc I would expect things to go wrong indeed.
bcbooo
Posts: 66
Joined: 22 November 2012, 06:41
Location: China

Re: COFE collapses when using CoUninitialize in destruction

Post by bcbooo »

Yeah, tc is a global variable.

tc is defined in a individual file:

Code: Select all

//header file, PublicVariable.h
extern CComPtr<ISample> tc;

Code: Select all

//cpp file, PublicVariable.cpp
CComPtr<ISample> tc=NULL;
User avatar
jasper
Posts: 1129
Joined: 24 October 2012, 15:33
Location: Spain
Contact:

Re: COFE collapses when using CoUninitialize in destruction

Post by jasper »

Why do you not make it a class variable?
User avatar
jasper
Posts: 1129
Joined: 24 October 2012, 15:33
Location: Spain
Contact:

Re: COFE collapses when using CoUninitialize in destruction

Post by jasper »

Alternatively, is this is an object to be shared by multiple unit operations, keep a reference count on it. Delete it when the last unit operation is deleted.

But this will surely give you thread safety problems. Suppose you have two threads that each have a unit operation, and that are calculating at the same time; they will be accessing the tc object simultaneously. You would need to synchronize access to this object.
bcbooo
Posts: 66
Joined: 22 November 2012, 06:41
Location: China

Re: COFE collapses when using CoUninitialize in destruction

Post by bcbooo »

tc is not shared by multiple Unit Operations, but shared by many functions in different classes. In my application tc is used to get some public data.

Now my strategy is not to call "tc=NULL" in destruction.
User avatar
jasper
Posts: 1129
Joined: 24 October 2012, 15:33
Location: Spain
Contact:

Re: COFE collapses when using CoUninitialize in destruction

Post by jasper »

This will not resolve your conflict regarding tc being used by two different unit operations. I suggest you make tc a member variable of the unit operation class.
Post Reply

Return to “COCO (AmsterCHEM)”