Protecting Shared Resources with a Temporary “Lease”

When protecting shared resources across multiple threads, developers will generally reach for a “mutex.”  As a refresher; a mutex is a type of object which ‘protects’ a resource, ensuring it is only accessed by a single consumer at a time; all other consumers are forced to wait in line. They must wait for the original consumer to release the mutex, before someone else can use it.

Think of a mutex like a key; you can only access the ‘locked’ resource as long as you’re holding the key.  If someone else holds the key, you have to wait for them to put it down before you can pick it up.

With this in mind, it should go without saying that a mutex should generally be held only for the minimum amount of time absolutely necessary.  When acquiring a mutex, users are encouraged to quickly finish their work so they can release the mutex to another consumer who might be waiting in line.

To some extent, this depends greatly on the shared ‘resource’ in question.  For a shared queue, it’s easy to quickly acquire a mutex, ‘pop’ the top item off the stack, and release the mutex – all without the user’s awareness.  For other resources however, consumers may need to hold a mutex for an extended period of time, through a series of complex operations.

For example: a connected “instrument” – such as a robot arm, or stepper motor – may need to be ‘reserved’ by a consumer for an extended period of time.  It may need to perform many complex operations before the consumer is ready to release the mutex for someone else to use.

In cases like these, it is dangerous to rely on the consumer of a resource to reliably lock and unlock the mutex themselves.  It would be so much more convenient and safe, if we could somehow package the resource and the mutex together, ensuring that one is always included with the other.

Enter the “lease” object.

Continue reading “Protecting Shared Resources with a Temporary “Lease””

Using std::unique_ptr with “Legacy” output APIs

A basic tenet of modern C++ programming; for leak-free code, you must use std::unique_ptr  and/or std::shared_ptr  by default.  Any time you allocate memory, it should be placed immediately into a smart pointer.  Ideally, the smart pointer’s initialization will also occur on the same line of code as the memory allocation:

There are times, however, when your application must interact with – *gasp!* – legacy APIs. Legacy APIs which might allocate memory before handing off ownership to you, the client.  This article will discuss clean, convenient ways to ensure that memory allocated from a ‘legacy’ API is reliably placed into a smart pointer.

Continue reading “Using std::unique_ptr with “Legacy” output APIs”

Easier comparison operators with std::tie

Being able to arbitrarily ‘look up’ or fetch an element from a collection is a critical tool in almost all C++ applications – or any programming language, for that matter.  Typically, in C++, this common paradigm manifests through the use of an std::map<TKey, TItem>  or an std::unordered_map<TKey, TItem> .  When your lookup ‘key’ is a simple, built-in type – such as an enum, int or string – everything just ‘works,’ because those simple types have built-in comparison operators.

Trivial keys can have limited usefulness, however.  More often than not, we need more complex lookup keys, in the form of aggregate types.  This post describes some tricks you can use to easily create aggregate types and reduce boilerplate code. Continue reading “Easier comparison operators with std::tie”