Jump to content
  • Advertisement
Sign in to follow this  
andhow

Race condition with D3DX library

This topic is 4836 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I think I have come to the bottom of a very frustrating bug I was having in the project I am working on, and it points to a thread-safety bug within D3DX (or DirectX). (Tested with 2003, Summer 2004, February 2005, and April 2005) To confirm this, I created an extremely short test program that recreates the problem, posted here: http://students.cs.tamu.edu/law1521/StuffFolder/d3dx_thread_bug.cpp [Libs: d3d9.lib dxerr9.lib d3dx9.lib, CRT: [Debug] Multithreaded, Subsystem: console, Make a random image named "test.png" and put it in the same folder] The observed behavior is that when ::D3DXCreateTextureFromFile() and ID3DXSprite::End() have some race condition. If you run this program (and wait long enough), it'll crash in ID3DXSprite::End(). My request of post readers is to point out any obvious errors in my posted code or verify that it crashes at ::End() (or nearby) on their own machine.

Share this post


Link to post
Share on other sites
Advertisement
I'm not too femiliar with how this works exactly, but I'm thinking if one thread releases a texture that you've passes to a sprite, before the sprite actually draws (I'm guessing it only really draws on ->End() - since in some cases it needs to z-sort the sprites) - you'd crash when the sprite tries to use the released texture.

Try moving the ->End call into the critial section. That would prevent the texture from being released anywhere between the ->Draw() and ->End() calls.

Hope this helps :).

Share this post


Link to post
Share on other sites
If you check in the critical section, I copy 'texture' to 'local', and call AddRef() on local, so this absolutely gaurantees the texture not to be Release()d early. Furthermore, if ID3DXSprite follows the COM rules, when it keeps an internal COM pointer, it should call AddRef() internally. Thus, the texture is absolutely alive for the duration of ID3DXSprite's use of it.

Share this post


Link to post
Share on other sites
Quote:
Original post by andhow
If you check in the critical section, I copy 'texture' to 'local', and call AddRef() on local, so this absolutely gaurantees the texture not to be Release()d early. Furthermore, if ID3DXSprite follows the COM rules, when it keeps an internal COM pointer, it should call AddRef() internally. Thus, the texture is absolutely alive for the duration of ID3DXSprite's use of it.

You're releasing local before calling ID3DXSprite::End, which could be the one actually doing the drawing. So, consider this scenario:

1) Critical Section entered
2) local points to where texture points
3) Ref count incremented, ref count = 2
4) Critical section left
5) Critical section entered by thread
6) texture is released by thread, ref count = 1
7) thread leaves critical section
8) ID3DXSprite::Draw called with local
9) local released, ref count = 0, destroyed
10) Sprite now has a pointer to garbage

Share this post


Link to post
Share on other sites
Hah, yes I do Release() before Blitter::End(). Upon testing these changes, it doesn't crash implying that ID3DXSprite does not AddRef() its stored COM pointers (efficiency instead of adhering to COM standard?). So I'm wrong on both counts. Thank you.

Share this post


Link to post
Share on other sites
Quote:
Original post by andhow
Hah, yes I do Release() before Blitter::End(). Upon testing these changes, it doesn't crash implying that ID3DXSprite does not AddRef() its stored COM pointers (efficiency instead of adhering to COM standard?). So I'm wrong on both counts. Thank you.

I'm kind of surprised by not addref-ing too. It doesn't feel right. Try to remove the thread totally and check what happens when you release the texture sent to the sprite before calling ID3DXSprite::End. If it crashes then - confirming that it doesn't addref - I'd say it should be reported as a bug.

Share this post


Link to post
Share on other sites
Quote:
Original post by andhow
I tried and it does indeed crash. At the very least it should be documented.


I've logged a bug for this. Either it will get changed or doc'd (different team, so not sure which it will be at this point).

Paul Bleisch

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!