A Flag with Exclusion. Flagex is a son of Mutex that contains a Flag. Hence the name, a combination of FLAG and mutEX. It is a sort of synchronization object you can use when your object needs both to implement a wait-for-notification function as well as to lock and unlock like Mutex objects can. It works on the same principle as Java's "monitor lock." The main difference is that Flagex cannot notify a single thread; Flagex_notify is the equivalent of Java's Object.notifyAll().
Flagex offers three main functions:
Constructs a named Flagex object.
#include <cywin.h> ... struct Flagex wait_for_data; ... Flagex_ctor( &wait_for_data, "data_ready" ); ... if( Flagex_wait( &wait_for_data, 1000 ) ) { // Uses shared data. ... } else { TRACE( "Timeout while waiting for data." ); } ... Flagex_dtor( &wait_for_data, LEAVE_MEMORY ); ...
Destructor.
#include <cywin.h> ... struct Flagex wait_for_data; ... Flagex_ctor( &wait_for_data, "data_ready" ); ... if( Flagex_wait( &wait_for_data, 1000 ) ) { // Uses shared data. ... } else { TRACE( "Timeout while waiting for data." ); } ... Flagex_dtor( &wait_for_data, LEAVE_MEMORY ); ...
Checks whether Mutex is locked.
#include <cywin.h> ... struct module_t main_module; struct Flagex wait_for_data; ... Flagex_ctor( &wait_for_data, "data_ready" ); while( Flagex_is_locked( &wait_for_data ) ) { sleep( 250 ); } Flagex_lock( &wait_for_data, 0 ); ... // Uses shared data. ... Flagex_unlock( &wait_for_data); ... Flagex_dtor( &wait_for_data, LEAVE_MEMORY ); ...
Returns a lock.
It attempts to get the lock for specified time. Note that if you already locked it, another Flagex_lock() operation has no additive effect. The first Flagex_unlock() call unlocks it immediately no matter how many times you've called the Flagex_lock() method. Be careful when designing your Flagexes logic!
#include <cywin.h> ... struct module_t main_module; struct Flagex wait_for_data; ... Flagex_ctor( &wait_for_data, "data_ready" ); while( Flagex_is_locked( &wait_for_data ) ) { sleep( 250 ); } Flagex_lock( &wait_for_data, 0 ); ... // Uses shared data. ... Flagex_unlock( &wait_for_data); ... Flagex_dtor( &wait_for_data, LEAVE_MEMORY ); ...
Notifies all waiting threads.
All threads that called Flagex_wait() for this object will be waked up. Note that they won't start until you will unlock the object, and that most priority one (and, though not guaranteed, first called wait() from top priority threads) will get the lock and actually start. You must have a lock on the object to call this method.
#include <cywin.h> ... struct Flagex wait_for_data; ... Flagex_ctor( &wait_for_data, "data_ready" ); ... // Prepares data. ... Flagex_notify( &wait_for_data ); ... Flagex_dtor( &wait_for_data, LEAVE_MEMORY ); ...
Unlocks Flagex.
Note that if you did not lock it before, the system ignores the unlock command and prints warning on the console. Also be warned: Flagex_unlock() releases the lock immediately, no matter how many times Flagex_lock() was called. Only the first Flagex_unlock() works; any repeared calls will be ignored.
#include <cywin.h> ... struct module_t main_module; struct Flagex wait_for_data; ... Flagex_ctor( &wait_for_data, "data_ready" ); while( Flagex_is_locked( &wait_for_data ) ) { sleep( 250 ); } Flagex_lock( &wait_for_data, 0 ); ... // Uses shared data. ... Flagex_unlock( &wait_for_data); ... Flagex_dtor( &wait_for_data, LEAVE_MEMORY ); ...
Waits for notification.
Puts the calling thread to sleep until some other thread calls Flagex_notify(). You must have a lock on this object to call it.
#include <cywin.h> ... struct Flagex wait_for_data; ... Flagex_ctor( &wait_for_data, "data_ready" ); ... if( Flagex_wait( &wait_for_data, 1000 ) ) { // Uses shared data. ... } else { TRACE( "Timeout while waiting for data." ); } ... Flagex_dtor( &wait_for_data, LEAVE_MEMORY ); ...