From b6cfbd077e9453dd16e09fff22ec014bc1ee282d Mon Sep 17 00:00:00 2001 From: Andre Heinecke Date: Wed, 29 Aug 2018 10:24:14 +0200 Subject: [PATCH] Add generic cache for IDispatch objects * src/dispcache.cpp, src/dispcache.h: New. * src/gpgoladdin.cpp, src/gpgoladdin.h: Carry dispcache as member. * src/Makefile.am: Add new Files. -- The cache shares the lifetime of the addin object and can be used to keep IDispatch object around without having to create them again and again. --- src/Makefile.am | 1 + src/dispcache.cpp | 114 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/dispcache.h | 60 ++++++++++++++++++++++++++++ src/gpgoladdin.cpp | 4 +- src/gpgoladdin.h | 4 ++ 5 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 src/dispcache.cpp create mode 100644 src/dispcache.h diff --git a/src/Makefile.am b/src/Makefile.am index 599394f..7906794 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -35,6 +35,7 @@ gpgol_SOURCES = \ cpphelp.cpp cpphelp.h \ cryptcontroller.cpp cryptcontroller.h \ dialogs.h \ + dispcache.h dispcache.cpp \ eventsink.h \ eventsinks.h \ exechelp.c exechelp.h \ diff --git a/src/dispcache.cpp b/src/dispcache.cpp new file mode 100644 index 0000000..7b1bbf3 --- /dev/null +++ b/src/dispcache.cpp @@ -0,0 +1,114 @@ +/* Copyright (C) 2018 Intevation GmbH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GpgOL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +#include "dispcache.h" +#include "gpg-error.h" + +#include "common.h" +#include "gpgoladdin.h" + +#include + +GPGRT_LOCK_DEFINE (cache_lock); + +class DispCache::Private +{ +public: + Private() + { + + } + + void addDisp (int id, LPDISPATCH obj) + { + if (!id || !obj) + { + TRACEPOINT; + return; + } + gpgrt_lock_lock (&cache_lock); + auto it = m_cache.find (id); + if (it != m_cache.end ()) + { + log_debug ("%s:%s Item \"%i\" already cached. Replacing it.", + SRCNAME, __func__, id); + gpgol_release (it->second); + it->second = obj; + gpgrt_lock_unlock (&cache_lock); + return; + } + m_cache.insert (std::make_pair (id, obj)); + gpgrt_lock_unlock (&cache_lock); + return; + } + + LPDISPATCH getDisp (int id) + { + if (!id) + { + TRACEPOINT; + return nullptr; + } + gpgrt_lock_lock (&cache_lock); + + const auto it = m_cache.find (id); + if (it != m_cache.end()) + { + LPDISPATCH ret = it->second; + gpgrt_lock_unlock (&cache_lock); + return ret; + } + gpgrt_lock_unlock (&cache_lock); + return nullptr; + } + + ~Private () + { + gpgrt_lock_lock (&cache_lock); + for (const auto it: m_cache) + { + gpgol_release (it.second); + } + gpgrt_lock_unlock (&cache_lock); + } + +private: + std::unordered_map m_cache; +}; + +DispCache::DispCache (): d (new Private) +{ +} + +void +DispCache::addDisp (int id, LPDISPATCH obj) +{ + d->addDisp (id, obj); +} + +LPDISPATCH +DispCache::getDisp (int id) +{ + return d->getDisp (id); +} + +DispCache * +DispCache::instance () +{ + return GpgolAddin::get_instance ()->get_dispcache ().get (); +} diff --git a/src/dispcache.h b/src/dispcache.h new file mode 100644 index 0000000..465665d --- /dev/null +++ b/src/dispcache.h @@ -0,0 +1,60 @@ +/* @file dispcache.h + * @brief Cache for IDispatch objects that are reusable. + * + * Copyright (C) 2018 Intevation GmbH + * + * This file is part of GpgOL. + * + * GpgOL is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * GpgOL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ +#ifndef DISPCACHE_H +#define DISPCACHE_H + +#include "config.h" + +#include + +#include "oomhelp.h" + +class GpgolAddin; + +class DispCache +{ + friend class GpgolAddin; +protected: + DispCache (); + +public: + /* Accessor. Returns the instance carried by + gpgoladdin. */ + static DispCache *instance (); + + /* Add a IDispatch with the id id to the cache. + + The IDispatch is released on destruction of + the cache. + + Id's are meant to be defined in dialogs.h + */ + void addDisp (int id, LPDISPATCH obj); + + /* Get the according IDispatch object. */ + LPDISPATCH getDisp (int id); + +private: + class Private; + std::shared_ptr d; +}; + +#endif diff --git a/src/gpgoladdin.cpp b/src/gpgoladdin.cpp index abf8e71..e331b86 100644 --- a/src/gpgoladdin.cpp +++ b/src/gpgoladdin.cpp @@ -47,6 +47,7 @@ #include "mail.h" #include "addin-options.h" #include "cpphelp.h" +#include "dispcache.h" #include #include @@ -178,7 +179,8 @@ GpgolAddin::GpgolAddin (void) : m_lRef(0), m_explorersEventSink(nullptr), m_disabled(false), m_shutdown(false), - m_hook(nullptr) + m_hook(nullptr), + m_dispcache(new DispCache) { read_options (); /* RibbonExtender is it's own object to avoid the pitfalls of diff --git a/src/gpgoladdin.h b/src/gpgoladdin.h index a8c121b..1641942 100644 --- a/src/gpgoladdin.h +++ b/src/gpgoladdin.h @@ -27,9 +27,11 @@ #include "mymapi.h" #include +#include class GpgolAddinRibbonExt; class ApplicationEventListener; +class DispCache; /* Enums for the IDTExtensibility2 interface*/ typedef enum @@ -212,6 +214,7 @@ public: crypto mails. */ void shutdown (); LPDISPATCH get_application () { return m_application; } + std::shared_ptr get_dispcache () { return m_dispcache; } bool isShutdown() { return m_shutdown; }; private: @@ -227,6 +230,7 @@ private: bool m_shutdown; HHOOK m_hook; std::vector m_explorerEventSinks; + std::shared_ptr m_dispcache; }; class GpgolAddinFactory: public IClassFactory -- 2.11.0