Multithreading UtilitiesAvailability LightWave 6.0 The multithreading global supplies a mutex (mutual exclusion) mechanism for managing threaded execution of your plug-in. LightWave may invoke your plug-in from multiple threads simultaneously, which has the effect of threading your code. But when doing certain things, for example when reading and writing global data, the threads of your code should be executed one at a time, rather than all at once. The mutex mechanism is a way for the threads of your code to cooperate in waiting for one another. Think of a mutex as a dressing room, a place where a thread can have some privacy. Any time your plug-in needs to do something synchronously (one thread at a time), you ask to be let into the dressing room by calling lock. If another thread (another "you") is already in that dressing room, your thread waits until the other thread is done. Then your thread gets the dressing room, and other threads that want that dressing room must wait for you to finish. When you're finished, you call unlock. The LWMTUtilID returned by the create function allows you to use up to 10 separate mutexes. These are numbered from 0 to 9 and are passed as the second argument to lock and unlock. You might think of these as 10 different dressing rooms. Multithreading is a complex topic. If you're unfamiliar with it, you're encouraged to seek out a general programming text that discusses the writing of thread-safe code. Global Call LWMTUtilFuncs *mtutil; mtutil = global( LWMTUTILFUNCS_GLOBAL, GFUSE_TRANSIENT ); The global function returns a pointer to an LWMTUtilFuncs. typedef struct st_LWMTUtilFuncs { LWMTUtilID (*create) (void); void (*destroy)(LWMTUtilID mtid); int (*lock) (LWMTUtilID mtid, int mutexID); int (*unlock) (LWMTUtilID mtid, int mutexID); } LWMTUtilFuncs;
Example This code fragment outlines the sequence of steps you'd take to use a mutex. #include <lwmtutil.h> LWMTUtilFuncs *mtutil; LWMTUtilID mtid; mtutil = global( LWMTUTILFUNCS_GLOBAL, GFUSE_TRANSIENT ); if ( !mtutil ) ...global not available, do this some other way... /* create the mutex */ mtid = mtutil->create(); ... /* enclose critical code (code that must run synchronously) in matching lock()/unlock() calls */ if ( mtutil->lock( mtid, 0 )) { ...do something that can't be threaded... mtutil->unlock( mtid, 0 ); } ... /* free the mutex when you no longer need it */ if ( mtid ) mtutil->destroy( mtid ); |