Domanda

To learn C# native interop, I've been working on an OpenGL wrapper. The OpenGL API itself is a state machine which is bound to a specific thread. When an object containing native resources is garbage collected, the finalizer is running in the GC thread, and cannot directly free the resources.

The workaround I currently have is to have a list in the context object, which the objects add their resources to and at a safe point in the draw loop it iterates through and frees them.

The problem with this, however, is that if the GC collects while it's iterating through that list, the foreach fails as the collection has been modified. I can't just put a mutex around the list as the GC is stop-the-world in most implementations and if the draw loop had locked it, it'd never complete the iteration and unlock it again.

Typically the MTBF is about two hours of gameplay, but if intentionally stress tested with a few thousand objects per second it happens in just a few seconds.

What might be the best approach here?

È stato utile?

Soluzione

Then you're going to bite the bullet and stop relying on the GC to do your resource management for you. You're going to have to have your asset manager have an explicit function to delete the objects it allocates, rather than relying on the asset manager's finalizer function. And you're going to have to call that function at a specific place in your code.

Just because you have GC doesn't mean it's the best or only solution.

Altri suggerimenti

Questioner wrote/stated:

The OpenGL API itself is a state machine which is bound to a specific thread.

This is wrong!

OpenGL contexts can be active in only one thread at a time. This doesn't mean, contexts can not be used from different threads. Essentially a OpenGL context is a mutually exclusive resource (hint: Mutex) that is to be bound before using it ({wgl,glX}MakeCurrent(DC, RC)) in a thread and after being done with whatever the context was required for, you unbind from the current thread the OpenGL context ({wgl,glX}MakeCurrent(NULL, NULL)).

You could always make use of the fixed statement.

See here http://msdn.microsoft.com/en-us/library/f58wzh21%28VS.80%29.aspx

It sounds as though your real problem is that you have objects with finalizers that expose their resources. If you are going to be using resources directly, you should create and store them in objects without finalizers, and make certain you exercise the discipline necessary to prevent resource leaks.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top