Solved

COM, Threads, Access Violation

Posted on 2004-08-09
6
717 Views
Last Modified: 2008-01-09
I am trying to write a program that created some objects and load files within a thread while the main program shows a progressbar. One of those objects is an object wrapping the DirectShow interface to play movies. When i just created and loaded without using an extra thread everything ran good. After finally crashes in an AccessViolation when trying to release an object created with CoCreateInstance.

Psuedo Code for the Problem area:

// start thread to create objects incl the directshow wrapper
// loop and update screen with the progress using a shared variable

when creating the objects i use CoCreateInstance(CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER, IID_IAMMultiMediaStream, (void **)&pAMStream).

Then when done i use this object in the main thread to update the multimedia stream and blit it to the correct surface.  First error that occures is that it does not play the file anymore. Besides that it raises an Access Violation when releasing the object.


Some real precies code

The code creating the thread:

      SECURITY_ATTRIBUTES sa = {      sizeof(SECURITY_ATTRIBUTES),       0,  TRUE      };
      hThread = (void*)_beginthreadex( &sa, 4096, func, &progress, 0, &threadid );  // func = a static function within a class that sets up the MultiMedia Object

The code creating the com object giving the problems within the MultiMedia object:

      HRESULT r;
      IAMMultiMediaStream *pAMStream;

      r = CoInitialize( NULL );
      if( r != S_OK ) return;

      if(FAILED(r=CoCreateInstance(CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER, IID_IAMMultiMediaStream, (void **)&pAMStream))) {
            Deinit();
            return;
      }
      pMMStream = pAMStream; //pMMStream is a member of the MultiMedia object

When updating the sample that is finally created but from the main thread it immidiately failed to play:

      HRESULT hr = pSample->Update( SSUPDATE_ASYNC, NULL, NULL, 0 );
      if( ( FAILED( hr ) || hr==MS_S_ENDOFSTREAM  ) && hr!=MS_E_BUSY ) { //stop if failed of success but end of stream.. dont stop when busy
            if( OnStop ) OnStop( this );  //callback
            return;
      }

And Finally it Crashes when the object is release:

      pMMStream->Release();

It's the only object giving a  problem. Other objects created with new work fine until deleted.

Remember that this all worked when I didn't use the extra thread.
Does anyone know/recognize the problem and have any tips or maybe a solution?


Thanks in advance.

Greetz,
Vincent
0
Comment
Question by:C0deJunkie
  • 3
  • 2
6 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 300 total points
ID: 11758701
Are you initializing COM as multithreaded, e.g.

CoInitializeEx(NULL, COINIT_MULTITHREADED);

?
0
 
LVL 9

Assisted Solution

by:_ys_
_ys_ earned 200 total points
ID: 11760337
In addition to jkr's comment, every thread that touches a COM object has to invoke CoInitialize[/Ex]. Naturally these are paired with calls to CoUninitialize before each thread terminates - but that's aside from your issue.
0
 
LVL 2

Author Comment

by:C0deJunkie
ID: 11760582
jkr.. No i haven't.

Should i use it instead of CoInitialize( NULL )? And then in both threads?

Im currently at work but i soon as i can test it, i will.

Greetz
Vincent
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 9

Expert Comment

by:_ys_
ID: 11760747
> Should i use it instead of CoInitialize( NULL )?
Recommended as your class is both multi-threaded and COM aware. If not then you'll have to, at worst, marshal any created interface pointers between different apartments - as scary to implement as it is to say.

> And then in both threads?
We mere mortals may not be jkr, but at times we do have something to input into answers ... lol.
<echo> every thread that touches a COM object has to invoke CoInitialize[/Ex] </echo>

Word of caution:
> pMMStream = pAMStream; //pMMStream is a member of the MultiMedia object
> pMMStream->Release();
Regarding those two lines of code. I'm assuming they're executing on different threads.

It's a dangerous coding technique where COM is involved. A basic COM rule is that if you copy an interface pointer AddRef it.

pMMStream = pAMStream; //pMMStream is a member of the MultiMedia object
pMMStream->AddRef ( );

This allows you to safely invoke pAMStream->Release ( ) and pMMStream->Release ( ).

You'd probably not invoke pAMStream->Release ( ) because you know not to. However some other poor soul maintaining your code might add it because they learnt it on a COM course somewhere.
0
 
LVL 2

Author Comment

by:C0deJunkie
ID: 11764866
Thanks to bothy of you guys/girls. I solved finally solved this problem.

_YS_, there isn't a second reference being created. That part of code is still from an example file. the scope of pAMStream is only the function creating the object. pMMStream is a class member. And i don't have any other poor soul working in this code. Its for my own, one man company, that i have beside the job i have paying my bills. PHP just isn't that challenging enough. So i started something for myself to atleast apply the c/c++ i leard over the past 15 years.

Greetz & Thanks
Vincent
0
 
LVL 9

Expert Comment

by:_ys_
ID: 11764934
If only my job would cover my bills ... poor soul -> reference to self
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

937 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

5 Experts available now in Live!

Get 1:1 Help Now