Solved

COM, Threads, Access Violation

Posted on 2004-08-09
6
711 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
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
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

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

762 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

22 Experts available now in Live!

Get 1:1 Help Now