GnomeVFS - Filesystem Abstraction library | |||
---|---|---|---|
<<< Previous Page | Home | Up | Next Page >>> |
Writing GNOME VFS modules is easy, but there are a few things that you must keep in mind when hacking them:
All of the code must be completely thread safe. The reason for this is that the asynchronous GNOME VFS engine will use threads when available; if you don't make sure that the code is thread-safe, every kind of weird and unexpected errors will happen. As debugging these problems can be very hard, it's important to write the code with threads in mind right from the start.
Use the special gnome_vfs_*_cancellable() VFS functions instead of the standard non-cancellable ones, passing them the same GnomeVFSCancellation object you are given, so that the operation can always be interrrupted at any time.
The code should respect the basic GNOME guidelines for source code indentation and style.
Although it might sound scary at first, making the code for the modules thread safe is not complicated at all.
First of all, make sure the amount of global variables is kept to the bare minimum. If possible, you should avoid them at all cost.
For those cases where globals are inevitable (such as caches, connection pools or things like that), you have to make sure every variable is properly associated with a mutex, and that the mutex is locked before every access to this variable and released afterwards. You can also use G_LOCK_DEFINE_STATIC, G_LOCK and G_UNLOCK for this.
Generally speaking, if you are going to dynamically allocate structures that are shared by more than one operation/file, you should provide all of them with their nice mutex locks.
Finally, make sure mutexes are used only if they are available. One way to do so is to use macros like the following:
#ifdef G_THREADS_ENABLED #define MUTEX_NEW() g_mutex_new () #define MUTEX_FREE(a) g_mutex_free (a) #define MUTEX_LOCK(a) if ((a) != NULL) g_mutex_lock (a) #define MUTEX_UNLOCK(a) if ((a) != NULL) g_mutex_unlock (a) #else #define MUTEX_NEW() NULL #define MUTEX_FREE(a) #define MUTEX_LOCK(a) #define MUTEX_UNLOCK(a) #endif |
G_LOCK_DEFINE_STATIC, G_LOCK and G_UNLOCK in GLib are always safe to use, as they are already defined to be nothing when thread support is not available.
(Probably it would be a good idea to have something in the private GNOME VFS API that does this stuff for all the modules.)