Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  Wrapper.h   Sprache: C

 
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#pragma once

/*
 * Wrapper - Helper class for wrapper objects.
 *
 * This helps to construct a shared_ptr object which wraps access to an
 * underlying handle. (The handle could be a pointer to some low-level type, a
 * conventional C handle, an int ID, a GUID, etc.)
 *
 * Usage:
 *   To obtain a FooPtr from a foo_handle_t, call
 *     FooPtr Foo::wrap(foo_handle_t);
 *
 * To implement Foo using Wrapper, Foo needs to include this macro in its class
 * definition:
 *   CSF_DECLARE_WRAP(Foo, foo_handle_t);
 * It also needs to include this in the cpp file, to provide the wrap()
 * implementation and define the static Wrapper.
 *   CSF_IMPLEMENT_WRAP(Foo, foo_handle_t);
 * These are all declared in common/Wrapper.h - Foo.h needs to include this
 * too.
 * The client needs to declare Foo(foo_handle_t) as private, and provide a
 * suitable implementation, as well as implementing wrappers for any other
 * functions to be exposed.
 * The client needs to implement ~Foo() to perform any cleanup as usual.
 *
 * wrap() will always return the same FooPtr for a given foo_handle_t, it will
 * not construct additional objects if a suitable one already exists.
 * changeHandle() is used in rare cases where the underlying handle is changed,
 *                but the wrapper object is intended to remain.  This is the
 *                case for the "fake" CC_DPCall generated on
 *                CC_DPLine::CreateCall(), where the correct IDPCall* is
 *                provided later.
 * reset() is a cleanup step to wipe the handle map and allow memory to be
 * reclaimed.
 *
 * Future enhancements:
 * - For now, objects remain in the map forever.  Better would be to add a
 *   releaseHandle() function which would allow the map to be emptied as
 *   underlying handles expired.  While we can't force the client to give up
 *   its shared_ptr<Foo> objects, we can remove our own copy, for instance on a
 *   call ended event.
 */


#include <map>
#include "prlock.h"
#include "mozilla/Assertions.h"

/*
 * Wrapper has its own autolock class because the instances are declared
 * statically and mozilla::Mutex will not work properly when instantiated
 * in a static constructor.
 */


class LockNSPR {
 public:
  LockNSPR() : lock_(nullptr) {
    lock_ = PR_NewLock();
    MOZ_ASSERT(lock_);
  }
  ~LockNSPR() { PR_DestroyLock(lock_); }

  void Acquire() { PR_Lock(lock_); }

  void Release() { PR_Unlock(lock_); }

 private:
  PRLock* lock_;
};

class AutoLockNSPR {
 public:
  explicit AutoLockNSPR(LockNSPR& lock) : lock_(lock) { lock_.Acquire(); }
  ~AutoLockNSPR() { lock_.Release(); }

 private:
  LockNSPR& lock_;
};

template <class T>
class Wrapper {
 private:
  typedef std::map<typename T::Handle, typename T::Ptr> HandleMapType;
  HandleMapType handleMap;
  LockNSPR handleMapMutex;

 public:
  Wrapper() {}

  typename T::Ptr wrap(typename T::Handle handle) {
    AutoLockNSPR lock(handleMapMutex);
    typename HandleMapType::iterator it = handleMap.find(handle);
    if (it != handleMap.end()) {
      return it->second;
    } else {
      typename T::Ptr p(new T(handle));
      handleMap[handle] = p;
      return p;
    }
  }

  bool changeHandle(typename T::Handle oldHandle,
                    typename T::Handle newHandle) {
    AutoLockNSPR lock(handleMapMutex);
    typename HandleMapType::iterator it = handleMap.find(oldHandle);
    if (it != handleMap.end()) {
      typename T::Ptr p = it->second;
      handleMap.erase(it);
      handleMap[newHandle] = p;
      return true;
    } else {
      return false;
    }
  }

  bool release(typename T::Handle handle) {
    AutoLockNSPR lock(handleMapMutex);
    typename HandleMapType::iterator it = handleMap.find(handle);
    if (it != handleMap.end()) {
      handleMap.erase(it);
      return true;
    } else {
      return false;
    }
  }

  void reset() {
    AutoLockNSPR lock(handleMapMutex);
    handleMap.clear();
  }
};

#define CSF_DECLARE_WRAP(classname, handletype)  \
 public:                                         \
  static classname##Ptr wrap(handletype handle); \
  static void reset();                           \
  static void release(handletype handle);        \
                                                 \
 private:                                        \
  friend class Wrapper<classname>;               \
  typedef classname##Ptr Ptr;                    \
  typedef handletype Handle;                     \
  static Wrapper<classname>& getWrapper() {      \
    static Wrapper<classname> wrapper;           \
    return wrapper;                              \
  }

#define CSF_IMPLEMENT_WRAP(classname, handletype)     \
  classname##Ptr classname::wrap(handletype handle) { \
    return getWrapper().wrap(handle);                 \
  }                                                   \
  void classname::reset() { getWrapper().reset(); }   \
  void classname::release(handletype handle) { getWrapper().release(handle); }

Messung V0.5
C=95 H=89 G=91

¤ Dauer der Verarbeitung: 0.42 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge