PDA

View Full Version : wglMakeCurrent returning ERROR_BUSY



Yogesh Kini
05-25-2007, 05:14 AM
Hi all,
I am trying to move my opengl rendering to a background thread.
But "wglMakeCurrent" is returning "ERROR_BUSY". This happens when I call the API from a different thread.
I am struck on my first step towards multi-threading.
Googling the error did not help any.
Has any one experienced the problem.
Any Idea when the error occurs?

Thanks for going through.
Besh Regards,
Yogesh

Olivier B.
05-25-2007, 05:37 AM
Hi,

Only thing that I know is OpenGL is not made to be used in Multi-Threaded program. You can make a thread to render, for physics, sounds, ... but not 2 threads using OpenGL.

Yogesh Kini
05-25-2007, 05:51 AM
Hi,
I am using only one thread for opengl rendering. All remaining threads are for UI and other jobs.

Regards
Yogesh

Olivier B.
05-25-2007, 06:02 AM
This happens when I call the API from a different thread Which API? OpenGL?

Yogesh Kini
05-25-2007, 06:25 AM
Which API? OpenGL? Well, I call "wglMakeCurrent" (API) on a different thread than the one that created the context.

Jackis
05-25-2007, 06:46 AM
Did you make your context shared after creation?

Yogesh Kini
05-25-2007, 07:08 AM
ok, I guess I need to explain in a bit of detail.
I only have one context. But I want to render into it through a background thread instead of the main thread.
So here is what I do:

Main thread I create a rendering context.
wglCreateContext

In the child or background thread I call
wglMakeCurrent to allow this thread to draw into this context.
But I get a False from this call(wglMakeCurrent).
When I call getLastError I get ERROR_BUSY.

Any Idea what's happening?
Regards
Yogesh Kini

Olivier B.
05-25-2007, 07:37 AM
Try to execute wglCreateContext in the background thread. If it works, it means that wglMakeCurrent need a context creation, or something like that, before being called in thread.

mfort
05-25-2007, 08:46 AM
I had the same problems as you have.
It was pretty random in my app. (Not all the time).
There must be some race condition inside the OS/driver.
So I did this bad trick:
for( int try=0; try is less then 20; try++) {
if( wglMakeCurrent ... is OK )
break;
Sleep(10);
}
Because it is done only during app initialization
I can live with this workaround. The try counter never reaches 3.
Yes I'm not very proud of it.
--
Marek

Olivier B.
05-25-2007, 09:04 AM
It was pretty random in my app Its not exactly random, but it depend on how your OS switch between thread, and it change depending on current CPU charge.

yooyo
05-25-2007, 09:52 AM
You must "release" context in current thread before you make it current in another thread. To release contex call:
thread 1: wglMakeCurrent(dc, NULL)
thread 2: wglMakeCurrent(dc, ctx);

or.. you can create context in thread 1 but do not make it current for that thread. Just pass ctx & dc to thread 2 and call wglMakeCurrent in thread 2.

Note that you can call SetPixelFormat only once per DC and do not try to change DisplayMode after you create gl context (all further wglMakeCurrent calls might fall).