/*
******************************************************************************
*
*   Copyright (C) 1997-2013, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
******************************************************************************
*/
//----------------------------------------------------------------------------
// File:     mutex.h
//
// Lightweight C++ wrapper for umtx_ C mutex functions
//
// Author:   Alan Liu  1/31/97
// History:
// 06/04/97   helena         Updated setImplementation as per feedback from 5/21 drop.
// 04/07/1999  srl               refocused as a thin wrapper
//
//----------------------------------------------------------------------------
#ifndef MUTEX_H
#define MUTEX_H

#include "unicode/utypes.h"
#include "unicode/uobject.h"
#include "umutex.h"

U_NAMESPACE_BEGIN

//----------------------------------------------------------------------------
// Code within that accesses shared static or global data should
// should instantiate a Mutex object while doing so. You should make your own 
// private mutex where possible.

// For example:
// 
// UMutex myMutex;
// 
// void Function(int arg1, int arg2)
// {
//    static Object* foo;     // Shared read-write object
//    Mutex mutex(&myMutex);  // or no args for the global lock
//    foo->Method();
//    // When 'mutex' goes out of scope and gets destroyed here, the lock is released
// }
//
// Note:  Do NOT use the form 'Mutex mutex();' as that merely forward-declares a function
//        returning a Mutex. This is a common mistake which silently slips through the
//        compiler!!
//

class U_COMMON_API Mutex : public UMemory {
public:
  inline Mutex(UMutex *mutex = NULL);
  inline ~Mutex();

private:
  UMutex   *fMutex;

  Mutex(const Mutex &other); // forbid copying of this class
  Mutex &operator=(const Mutex &other); // forbid copying of this class
};

inline Mutex::Mutex(UMutex *mutex)
  : fMutex(mutex)
{
  umtx_lock(fMutex);
}

inline Mutex::~Mutex()
{
  umtx_unlock(fMutex);
}

// common code for singletons ---------------------------------------------- ***

/**
 * Function pointer for the instantiator parameter of
 * SimpleSingleton::getInstance() and TriStateSingleton::getInstance().
 * The function creates some object, optionally using the context parameter.
 * The function need not check for U_FAILURE(errorCode).
 */
typedef void *InstantiatorFn(const void *context, UErrorCode &errorCode);

/**
 * Singleton struct with shared instantiation/mutexing code.
 * Simple: Does not remember if a previous instantiation failed.
 * Best used if the instantiation can really only fail with an out-of-memory error,
 * otherwise use a TriStateSingleton.
 * Best used via SimpleSingletonWrapper or similar.
 * Define a static SimpleSingleton instance via the STATIC_SIMPLE_SINGLETON macro.
 */
struct SimpleSingleton {
    void      *fInstance;
    UInitOnce  fInitOnce;

    /**
     * Returns the singleton instance, or NULL if it could not be created.
     * Calls the instantiator with the context if the instance has not been
     * created yet. 
     */
    void *getInstance(InstantiatorFn *instantiator, const void *context,
                      UErrorCode &errorCode);
    /**
     * Resets the fields. The caller must have deleted the singleton instance.
     * Not mutexed.
     * Call this from a cleanup function.
     */
    void reset() { fInstance=NULL; fInitOnce.reset(); }
};

#define SIMPLE_SINGLETON_INITIALIZER {NULL, U_INITONCE_INITIALIZER}
#define STATIC_SIMPLE_SINGLETON(name) static SimpleSingleton name = SIMPLE_SINGLETON_INITIALIZER

/**
 * Handy wrapper for a SimpleSingleton.
 * Intended for temporary use on the stack, to make the SimpleSingleton easier to deal with.
 * Takes care of the duplicate deletion and type casting.
 */
template<typename T>
class SimpleSingletonWrapper {
public:
    SimpleSingletonWrapper(SimpleSingleton &s) : singleton(s) {}
    void deleteInstance() {
        delete (T *)singleton.fInstance;
        singleton.reset();
    }
    T *getInstance(InstantiatorFn *instantiator, const void *context,
                   UErrorCode &errorCode) {
        T *instance=(T *)singleton.getInstance(instantiator, context, errorCode);
        return instance;
    }
private:
    SimpleSingleton &singleton;
};

/**
 * Singleton struct with shared instantiation/mutexing code.
 * Tri-state: Instantiation succeeded/failed/not attempted yet.
 * Best used via TriStateSingletonWrapper or similar.
 * Define a static TriStateSingleton instance via the STATIC_TRI_STATE_SINGLETON macro.
 */
struct TriStateSingleton {
    void       *fInstance;
    UErrorCode  fErrorCode;
    UInitOnce   fInitOnce;

    /**
     * Returns the singleton instance, or NULL if it could not be created.
     * Calls the instantiator with the context if the instance has not been
     * created yet.
     * The singleton creation is only attempted once. If it fails,
     * the singleton will then always return NULL.
     */
    void *getInstance(InstantiatorFn *instantiator, const void *context,
                      UErrorCode &errorCode);
    /**
     * Resets the fields. The caller must have deleted the singleton instance.
     * Not mutexed.
     * Call this from a cleanup function.
     */
    void reset();
};

#define STATIC_TRI_STATE_SINGLETON(name) static TriStateSingleton name={ NULL, U_ZERO_ERROR, U_INITONCE_INITIALIZER }

/**
 * Handy wrapper for a TriStateSingleton.
 * Intended for temporary use on the stack, to make the TriStateSingleton easier to deal with.
 * Takes care of the duplicate deletion and type casting.
 */
template<typename T>
class TriStateSingletonWrapper {
public:
    TriStateSingletonWrapper(TriStateSingleton &s) : singleton(s) {}
    void deleteInstance() {
        delete (T *)singleton.fInstance;
        singleton.reset();
    }
    T *getInstance(InstantiatorFn *instantiator, const void *context,
                   UErrorCode &errorCode) {
        T *instance=(T *)singleton.getInstance(instantiator, context, errorCode);
        return instance;
    }
private:
    TriStateSingleton &singleton;
};

U_NAMESPACE_END

#endif //_MUTEX_
//eof
