[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 785
  • Last Modified:

COM, Threads, Access Violation

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
C0deJunkie
Asked:
C0deJunkie
  • 3
  • 2
2 Solutions
 
jkrCommented:
Are you initializing COM as multithreaded, e.g.

CoInitializeEx(NULL, COINIT_MULTITHREADED);

?
0
 
_ys_Commented:
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
 
C0deJunkieAuthor Commented:
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
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
_ys_Commented:
> 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
 
C0deJunkieAuthor Commented:
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
 
_ys_Commented:
If only my job would cover my bills ... poor soul -> reference to self
0

Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now