Stopping Simultaneous File Access

BlitzMax Forums/BlitzMax Programming/Stopping Simultaneous File Access

Luke111(Posted 2012) [#1]
Hello all,
I have a (quite large) application I am writing. It has a couple of problems, and I am not going to ask you to fix it. I just need some help with concepts.

This application (could) load from and save to the same file(s) at the same time. This is not the desired effect, of course.
Pretty much, I need a mutex on the file, kindof like a lockfile, which I believe only works for processes, not threads.

Should I make a type which contains the file name and a mutex, and instantiate that type on the first access of the file; then use that mutex to stop more than one operation on the file at any given time, saving all the instances of this type in a list with another mutex protecting it, stopping multiple threads from adding/retrieving the filename/mutex data from this list simultaneously? Or is there a better way?

Thanks!
Luke


GfK(Posted 2012) [#2]
If you're using threads surely you can just use a mutex in your load/save functions to make sure they cannot both be happening at the same time? Don't know enough about threads (or your code) to give any specific advice but that's the first thing that comes to mind.


Yasha(Posted 2012) [#3]
Uh, have you tested this? There's a reason why the "lock file pattern" exists... and that is that the OS is already supposed to detect this sort of thing for you: it should fail to open a file that's already in use.

I could be being stupid and misremembering whether Blitz actually does this by default, but at any rate the service is certainly already available at the OS level, and if it's not default behaviour for files to be locked, then you can certainly achieve this using system calls instead.


Luke111(Posted 2012) [#4]
GfK: Theoretically that's what I was thinking. The problem is that there is more than one file, so I wanted to do (basically) a list of mutexes that are associated with the each individual file. The application is my Minecraft clone, and the problem is loading and saving the data files. The way I am doing it is to run-length-encode each 16x128x16 blocks, then store them in a file as a string. Every chunk has it's own file for quick access. Once you go out of range of a chunk (thats 16x128x16 blocks), the chunk is sent to the disk and data is unloaded from the program. If you have been to a chunk before, it loads it from the file when you get close, otherwise it randomly generates a new one.

Also (I know, not the best idea) whenever you build or delete from a chunk, it saves it on the disk. But I plan to get rid of that shortly, making it more streamlined.

There is a thread for every chunk being loaded, and saved. That is where the problem is. If you delete a block, then run off the chunk fast, it may try to save it while saving it, or load it while saving it, or something weird like that.


Luke111(Posted 2012) [#5]
Yasha: So, does that only apply to the process, or to the threads of the process? And I will look at the brl code to see if it does or does not lock the file from being accessed again. I believe that there is a parameter in the open file call that will say whether to or not.


Derron(Posted 2012) [#6]
Use your own lockfiles (like libre/openoffice does)
1) user wants to open openfile.txt
2) writeable = file_exists(openfile.txt.lock) ? true : false
3) create openfile.txt.lock if not existing and writeable
4) save
5) quit ? delete openfile.txt.lock : ...


Should be enough.

bye
Ron