views:

96

answers:

2

I'm currently using the following code for thread-safe access of a variable.

int gnVariable;

void getVariableValue(int *pnValue)
{
    acquireLock(); //Acquires the protection mechanism
    *pnValue = gnVariable;
    releaseLock(); //Releasing the protection mechanism
}

I would like to change my API signature to a more user-friendly

int getVariableValue(void);

How should I rewrite the function - such that the users of the API don't have to bother about the locking/unlocking details?

+8  A: 

You return a copy of the local variable. Something like:

int getVariableValue(void)
{
  int local= 0;
  acquireLock();
  local = gnVariable;
  releaseLock();
  return local;
}

As a side note, it is better to RAII principle for locking instead of acquireLock and releaseLock methods.

Naveen
the local copy seems somewhat inelegant. :) No other go?
sonofdelphi
@sonofdelphi: @R Samuel Klatchko is a better solution. I just wanted to demonstrate how to do it using local copy.
Naveen
@sonofdelphi: The local variable should be optimised away by a decent compiler - it will copy the `gnVariable` straight into the return value location.
caf
+8  A: 

Since you gave C++ as an option, you can wrap the mutex lock/unlock. You can then return the value directly:

class lock_wrapper
{
public:
    lock_wrapper()
    {
        acquireLock();
    }
    ~lock_wrapper()
    {
        releaseLock();
    }
};

int getVariableValue()
{
    lock_wrapper lw;
    return gnVariable;
}

This will also come in handy if you ever need to do a lock/unlock around code that can throw an exception.

R Samuel Klatchko
any ideas for doing the same in C?
sonofdelphi
I used to use Counting Semaphores for this. Counting Semaphores in some RTOSs support the getValue() operation, which operates atomically.
sonofdelphi
@sonofdelphi - for C, you should use the technique from Naveen's answer.
R Samuel Klatchko