I am trying to figure out how to override file callbacks using FMOD::setFileSystem(). The file_callback example shows the syntax fairly clearly, but I’m not sure quite how to connect it up to our game’s resource loading system.
Our system is asynchronous, where a background thread is responsible for all the actual file accesses. Requests for files are sent from the main thread, and there is an update() call per frame that will trigger delivery notifications (on the main game thread as that is what calls update) for resources that were requested earlier and have become available.
I am not quite sure how best to interface this with our system; it appears that FMOD has the implicit assumption that loading files is a synchronous operation. I could make the open callback block until the data is available, but that only works if FMOD only calls my file callbacks from background threads; if it calls from the main thread I cannot block there as the main thread needs to run in order for resource.update() to ever retrieve any file contents.
I looked through the documentation under ‘Threads and thread safety’ but it still is not entirely clear. It claims FMOD only uses 4 threads and 2 are automatically started, but then only lists 1 as being started by init().
I considered loading the data into memory before it is needed by FMOD, but that requires some clairvoyance on the part of the program, particularly as we are trying to use the Designer API and the loading of .fsb files seems to be conditional on runtime events. Should I return FMOD_ERR_FILE_COULDNOTSEEK or something similar to indicate that the data is not available (yet) but will be in the future?
- simubenc asked 8 years ago
You must give fmod data when it demands it, so yes you have to block.
For non blocking behaviour, you shouldnt be relying on your own system, fmod already has the systems internally to handle that (ie FMOD_NONBLOCKING flag, and the stream thread which does the file reads in the back ground).
If you use fmod’s nonblocking features, then from those threaded callbacks, simply block until your async system gives you data (i recommend waitsema/signalsema, not any form of waiting loop), then you should be fine.
Thanks for the response.
I have to use our resource loading system as FMOD does not understand the file format we are using for resources. The system is inherently non-blocking as it works asynchronously, I’m trying to figure out an appropriate way to wrap it to make it synchronous since that is what FMOD expects.
I should also mention that I am trying to use the event system, so I am not directly specifying FMOD_NONBLOCKING or FMOD_CREATESTREAM unless that system does it internally.
The documentation on threads suggests that using the nonblocking flag starts the async thread, and using the stream flag creates the stream thread and file reading thread. The implication, although it is never explicitly stated, is that the typical case would have FMOD making filesystem calls on the main thread. Empirical data shows that it does in fact do this.
I can’t block on this thread as that would interrupt a number of things that need to keep running (including the delivery of file data itself, which would end up causing a deadlock.) Spinning up a separate thread for FMOD does not help because while it’s blocked, the game can’t call into FMOD to do anything.
In the typical case delivery should be fast but there can be situations where resources take on the order of 10 seconds to become available. I don’t think that blocking inside FMOD for this long is okay.
- simubenc answered 8 years ago
Please login first to submit.