This section describes how to use critical sections to protect
portions of your adaptor code. The section describes the adaptor kit's
main critical section class, ICriticalSection
,
and the ancillary class, IAutoCriticalSection
,
that you use to manage critical sections. Topics covered include
To prevent sections of code or resources from being accessed
simultaneously by multiple threads, use critical section (ICriticalSecton
)
objects. The basic process for using a critical section has three-steps:
Create a critical section object, using
the adaptor kit createCriticalSection()
function.
At the point in your code that you want
to protect, enter the critical section by calling the ICriticalSection::enter()
member
function.
At the end of the code that you want
to protect, leave the critical section by calling the ICriticalSection::leave()
member
function.
While this process might appear simple, using a ICriticalSection
object
directly in this way can expose your adaptor to problems. For example,
if an error occurs in the protected code, the call to the leave()
function
might never be executed. Entering a critical section and then never
leaving it can cause unexpected results.
To make working with critical sections easier, the adaptor kit
provides a second class, called IAutoCriticalSection
,
that can help you manage the critical sections you define.
You first create an ICriticalSection
object
and then pass this object to the createAutoCriticalSection()
function
when you create the IAutoCriticalSection
object.
When you create the object, you automatically enter the critical section
without having to call the enter()
function. When
the protected code goes out of scope, the auto critical section automatically
leaves the critical section without your code having to call the leave()
function.
The auto critical section object ensures that you always exit
a critical section. However, you must also ensure that the auto critical
section itself gets deleted. To do this, the adaptor kit recommends
managing the handle to the IAutoCriticalSection
object,
returned by createAutoCriticalSection()
, as an auto_ptr
using
the std::auto_ptr<>
template class from the
Standard Template Library. The auto_ptr
helps ensure
that the IAutoCriticalSection
handle is deleted.
To define a section of code as a critical section, follow this procedure.
Create an ICriticalSection
object,
using the createCriticalSection()
function. Adaptors
typically create an ICriticalSection
object in
their constructors — see Implementing Your Adaptor Class Constructor.
_mySection = imaqkit::createCriticalSection();
The function returns a handle to an ICriticalSection
object. _mySection
,
which is declared as a member variable in the adaptor class header
file, as follows.
imaqkit::ICriticalSection* _mySection;
At the point in your code that you want
to protect, create an IAutoCriticalSection
object.
The IAutoCriticalSection
class guarantees that
the critical section objects are released when the protected code
goes out of scope, or if an exception occurs. In an adaptor, you typically
want to protect the frame acquisition loop in a critical section.
Insert this code in the acquisition thread function, just before the
frame acquisition loop — see Implementing the Acquisition Thread Function.
std::auto_ptr<imaqkit::IAutoCriticalSection> myAutoSection(imaqkit::createAutoCriticalSection(adaptor->_mySection, true));
In this code, the variable myAutoSection
is
a handle to an IAutoCriticalSection
object, that
is managed as a Standard Template Library auto_ptr
.
The code passes a handle to an ICriticalSection
object,
_mySection
, as an argument to the createAutoCriticalSection()
function.
The second argument to createAutoCriticalSection()
specifies
that the adaptor should enter the critical section automatically upon
creation of the IAutoCriticalSection
.
At the end of the code that you want to protect, leave the critical section. In an adaptor, you want to leave the critical section after the frame acquisition loop is done. Insert this code just before the acquisition thread function breaks out of the frame acquisition loop — see Implementing the Acquisition Thread Function.
You can use the IAutoCriticaSection::leave()
function
but this is not necessary. The IAutoCriticalSection
leaves
the critical section automatically when the code section goes out
of scope. You might want to include explicit calls to the leave()
function
in your code to help document the extent of your critical section.
bool MyDeviceAdaptor::stopCapture(){ // If the device is not acquiring data, return. if (!isAcquiring()) return true; // Get the critical section and enter it. std::auto_ptr<imaqkit::IAutoCriticalSection> GrabSection(imaqkit::createAutoCriticalSection(_grabSection, true)); //********************************************************** // Insert calls to your device's SDK to stop the device, if // necessary. //********************************************************** // Leave the critical section. GrabSection->leave(); return true; }