diff options
Diffstat (limited to 'salhelper/inc')
-rw-r--r-- | salhelper/inc/salhelper/condition.hxx | 124 | ||||
-rw-r--r-- | salhelper/inc/salhelper/dynload.hxx | 206 | ||||
-rw-r--r-- | salhelper/inc/salhelper/future.hxx | 120 | ||||
-rw-r--r-- | salhelper/inc/salhelper/futurequeue.hxx | 108 | ||||
-rw-r--r-- | salhelper/inc/salhelper/monitor.hxx | 288 | ||||
-rw-r--r-- | salhelper/inc/salhelper/queue.hxx | 174 | ||||
-rw-r--r-- | salhelper/inc/salhelper/refobj.hxx | 110 | ||||
-rwxr-xr-x | salhelper/inc/salhelper/simplereferenceobject.hxx | 136 | ||||
-rw-r--r-- | salhelper/inc/salhelper/singletonref.hxx | 210 |
9 files changed, 1476 insertions, 0 deletions
diff --git a/salhelper/inc/salhelper/condition.hxx b/salhelper/inc/salhelper/condition.hxx new file mode 100644 index 000000000000..de0664cd197d --- /dev/null +++ b/salhelper/inc/salhelper/condition.hxx @@ -0,0 +1,124 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _SALHELPER_CONDITION_HXX_ +#define _SALHELPER_CONDITION_HXX_ + + +#include <osl/conditn.h> +#include <osl/mutex.hxx> + + +namespace salhelper +{ + class ConditionModifier; + class ConditionWaiter; + + + class Condition + { + friend class ConditionModifier; + friend class ConditionWaiter; + + public: + + Condition(osl::Mutex& aMutex); + + virtual ~Condition(); + + + protected: + + virtual bool applies() const = 0; + + + private: + Condition(Condition &); // not defined + void operator =(Condition &); // not defined + + osl::Mutex& m_aMutex; + oslCondition m_aCondition; + }; + + + + class ConditionModifier + { + public: + + ConditionModifier(Condition& aCond); + + ~ConditionModifier(); + + + private: + ConditionModifier(ConditionModifier &); // not defined + void operator =(ConditionModifier &); // not defined + + Condition& m_aCond; + }; + + + + class ConditionWaiter + { + public: + + ConditionWaiter(Condition& aCond); + + struct timedout { + timedout(); + + timedout(timedout const &); + + virtual ~timedout(); + + timedout & operator =(timedout const &); + }; + + ConditionWaiter(Condition& aCond,sal_uInt32 milliSec) + throw( + timedout + ); + + + ~ConditionWaiter(); + + + private: + ConditionWaiter(ConditionWaiter &); // not defined + void operator =(ConditionWaiter &); // not defined + + Condition& m_aCond; + }; + + +} // namespace salhelper + + +#endif diff --git a/salhelper/inc/salhelper/dynload.hxx b/salhelper/inc/salhelper/dynload.hxx new file mode 100644 index 000000000000..cb657ec72ff1 --- /dev/null +++ b/salhelper/inc/salhelper/dynload.hxx @@ -0,0 +1,206 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SALHELPER_DYNLOAD_HXX_ +#define _SALHELPER_DYNLOAD_HXX_ + +#include <sal/types.h> +#include <rtl/ustring.hxx> +#include <osl/module.h> + +namespace salhelper +{ + +/** The ORealDynamicLoader is an implementation helper class for the template loader ODynamicLoader. + */ +class ORealDynamicLoader +{ +public: + /** initializes the loader, loads the library and call the initialization fucntion. + + @param ppSetToZeroInDestructor points to the loader instance which must be set to NULL + if the loader will be destroyed. + @param strModuleName specifies the library name. + @param strInitFunction specifies the name of the initialization function. + */ + static ORealDynamicLoader* SAL_CALL newInstance( + ORealDynamicLoader ** ppSetToZeroInDestructor, + const ::rtl::OUString& strModuleName, + const ::rtl::OUString& strInitFunction ); + + /// increase the reference count. + sal_uInt32 SAL_CALL acquire(); + /// decrease the reference count and delete the last instance. + sal_uInt32 SAL_CALL release(); + + /// returns a poiner to the initialized API function structure. + void* SAL_CALL getApi() const; + +protected: + /** Constructor. + + @param ppSetToZeroInDestructor points to the loader instance which must be set to NULL + if the loader will be destroyed. + @param strModuleName specifies the library name. + @param strInitFunction specifies the name of the initialization function. + @param pApi points to a structure with the initialized API function pointers. + @param pModule points to the loaded library handle. + */ + ORealDynamicLoader( ORealDynamicLoader ** ppSetToZeroInDestructor, + const ::rtl::OUString& strModuleName, + const ::rtl::OUString& strInitFunction, + void* pApi, + oslModule pModule ); + + /// Destructor, try to unload the library. + virtual ~ORealDynamicLoader(); + + /// points to the structure with the initialzed API function pointers. + void* m_pApi; + /// stores the reference count. + sal_uInt32 m_refCount; + /// stores the library handle. + oslModule m_pModule; + /// stores the library name. + ::rtl::OUString m_strModuleName; + /// stores the name of the initialization function. + ::rtl::OUString m_strInitFunction; + /** stores a pointer to itself, which must be reset in the destructor to signal + that the loader is invalid. + */ + ORealDynamicLoader ** ppSetToZeroInDestructor; +}; + + +/** The ODynmaicLoader provides a special load on call mechanism for dynamic libraries + which support a C-API. + + The libraries must provide a struct with function pointers for all supported C functions. + The loader loads the specified library and call the specified initialization function + to initialize the function pointers with the real functions. Furthermore provides the + loader a reference counter for the library. When the last instance of the laoder will + be destroyed the loader will unload the library. + + @deprecated + Do not use. + */ +template<class API> +class ODynamicLoader +{ +public: + /// Default constructor + ODynamicLoader() SAL_THROW(()) + { + m_pLoader = 0; + } + + /** Constructor, loads the library if necessary otherwise the refernece count will + be increased. + + @param strModuleName specifies the library name. + @param strInitFunction specifies the name of the initialization function. + */ + ODynamicLoader( const ::rtl::OUString& strModuleName, + const ::rtl::OUString& strInitFunction ) SAL_THROW(()) + { + if (!m_pStaticLoader) + { + m_pStaticLoader = ORealDynamicLoader::newInstance( + &m_pStaticLoader, + strModuleName, + strInitFunction); + } + else + { + m_pStaticLoader->acquire(); + } + + m_pLoader = m_pStaticLoader; + } + + /// Copy constructor + ODynamicLoader(const ODynamicLoader<API>& toCopy) SAL_THROW(()) + { + m_pLoader = toCopy.m_pLoader; + if( m_pLoader ) + m_pLoader->acquire(); + } + + /// Destructor, decrease the reference count and unload the library if it is tha last instance. + ~ODynamicLoader() SAL_THROW(()) + { + if( m_pLoader ) + m_pLoader->release(); + } + + /// Assign operator + ODynamicLoader<API>& SAL_CALL operator = (const ODynamicLoader<API>& toAssign) SAL_THROW(()) + { + if( m_pLoader != toAssign.m_pLoader ) + { + if( toAssign.m_pLoader ) + toAssign.m_pLoader->acquire(); + if( m_pLoader ) + m_pLoader->release(); + m_pLoader = toAssign.m_pLoader; + } + + return (*this); + } + + /// returns a poiner to the initialized API function structure. + API* SAL_CALL getApi() const SAL_THROW(()) + { + return (API*)m_pLoader->getApi(); + } + + /// cast operator, which cast to a poiner with the initialized API function structure. + API* SAL_CALL operator->() const SAL_THROW(()) + { + return (API*)m_pLoader->getApi(); + } + + /// checks if the loader works on a loaded and initialized library. + sal_Bool SAL_CALL isLoaded() const SAL_THROW(()) + { + return (m_pLoader != NULL); + } + +protected: + /// stores the real loader helper instance + static ORealDynamicLoader* m_pStaticLoader; + ORealDynamicLoader* m_pLoader; +}; + + +template<class API> +ORealDynamicLoader* ODynamicLoader<API>::m_pStaticLoader = NULL; + +} + +#endif + diff --git a/salhelper/inc/salhelper/future.hxx b/salhelper/inc/salhelper/future.hxx new file mode 100644 index 000000000000..a16b9c8815d6 --- /dev/null +++ b/salhelper/inc/salhelper/future.hxx @@ -0,0 +1,120 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SALHELPER_FUTURE_HXX_ +#define _SALHELPER_FUTURE_HXX_ + +#include <sal/types.h> +#include <osl/diagnose.h> +#include <osl/conditn.hxx> +#include <salhelper/refobj.hxx> + +namespace salhelper +{ + +//---------------------------------------------------------------------------- + +#ifndef SALHELPER_COPYCTOR_API +#define SALHELPER_COPYCTOR_API(C) C (const C&); C& operator= (const C&) +#endif + +//---------------------------------------------------------------------------- + +template<class value_type> +class FutureValue : protected osl::Condition +{ + /** Representation. + */ + value_type m_aValue; + + /** Not implemented. + */ + SALHELPER_COPYCTOR_API(FutureValue<value_type>); + +public: + inline FutureValue (const value_type& value = value_type()) SAL_THROW(()) + : m_aValue (value) + { + Condition::reset(); + } + + inline ~FutureValue() SAL_THROW(()) + {} + + inline sal_Bool is() const SAL_THROW(()) + { + return const_cast<FutureValue*>(this)->check(); + } + + inline void set (const value_type& value) SAL_THROW(()) + { + m_aValue = value; + Condition::set(); + } + + inline value_type& get() SAL_THROW(()) + { + Condition::wait(); + return m_aValue; + } +}; + +//---------------------------------------------------------------------------- + +template<class value_type> +class Future : public salhelper::ReferenceObject +{ + /** Representation. + */ + FutureValue<value_type> m_aValue; + + /** Not implemented. + */ + SALHELPER_COPYCTOR_API(Future<value_type>); + +public: + inline Future (const value_type& value = value_type()) SAL_THROW(()) + : m_aValue (value) + {} + + inline void set (const value_type& value) SAL_THROW(()) + { + OSL_PRECOND(!m_aValue.is(), "Future::set(): value already set"); + m_aValue.set (value); + } + + inline value_type& get() SAL_THROW(()) + { + return m_aValue.get(); + } +}; + +//---------------------------------------------------------------------------- + +} // namespace salhelper + +#endif /* !_SALHELPER_FUTURE_HXX_ */ diff --git a/salhelper/inc/salhelper/futurequeue.hxx b/salhelper/inc/salhelper/futurequeue.hxx new file mode 100644 index 000000000000..64915317440b --- /dev/null +++ b/salhelper/inc/salhelper/futurequeue.hxx @@ -0,0 +1,108 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SALHELPER_FUTUREQUEUE_HXX_ +#define _SALHELPER_FUTUREQUEUE_HXX_ + +#include <sal/types.h> +#include <rtl/ref.hxx> +#include <osl/mutex.hxx> +#include <salhelper/future.hxx> +#include <salhelper/queue.hxx> + +namespace salhelper +{ + +//---------------------------------------------------------------------------- + +#ifndef SALHELPER_COPYCTOR_API +#define SALHELPER_COPYCTOR_API(C) C (const C&); C& operator= (const C&) +#endif + +//---------------------------------------------------------------------------- + +template<class element_type> +class FutureQueue : protected osl::Mutex +{ + /** Representation. + */ + typedef salhelper::Future<element_type> future_type; + + salhelper::QueueBase< rtl::Reference<future_type> > m_aDelayed; + salhelper::QueueBase< rtl::Reference<future_type> > m_aPresent; + + /** Not implemented. + */ + SALHELPER_COPYCTOR_API(FutureQueue<element_type>); + +public: + /** Construction. + */ + inline FutureQueue() + {} + + /** Destruction. + */ + inline ~FutureQueue() + {} + + /** Enqueue element at queue tail. + */ + inline void put (const element_type& element) + { + osl::MutexGuard aGuard (*this); + + rtl::Reference<future_type> xFuture (m_aDelayed.get()); + if (!xFuture.is()) + { + xFuture = new future_type(); + m_aPresent.put (xFuture); + } + xFuture->set (element); + } + + /** Dequeue a future to element at queue head. + */ + inline rtl::Reference< salhelper::Future<element_type> > get() + { + osl::MutexGuard aGuard (*this); + + rtl::Reference<future_type> xFuture (m_aPresent.get()); + if (!xFuture.is()) + { + xFuture = new future_type(); + m_aDelayed.put (xFuture); + } + return (xFuture); + } +}; + +//---------------------------------------------------------------------------- + +} // namespace salhelper + +#endif /* !_SALHELPER_FUTUREQUEUE */ diff --git a/salhelper/inc/salhelper/monitor.hxx b/salhelper/inc/salhelper/monitor.hxx new file mode 100644 index 000000000000..5c683d386570 --- /dev/null +++ b/salhelper/inc/salhelper/monitor.hxx @@ -0,0 +1,288 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SALHELPER_MONITOR_HXX_ +#define _SALHELPER_MONITOR_HXX_ + +#include <sal/types.h> +#include <osl/conditn.hxx> +#include <osl/diagnose.h> +#include <osl/interlck.h> +#include <rtl/ref.hxx> +#include <salhelper/refobj.hxx> +#include <salhelper/future.hxx> +#include <salhelper/futurequeue.hxx> + +namespace salhelper +{ + +//---------------------------------------------------------------------------- + +#ifndef SALHELPER_COPYCTOR_API +#define SALHELPER_COPYCTOR_API(C) C (const C&); C& operator= (const C&) +#endif + +//---------------------------------------------------------------------------- + +class MonitorCondition : protected osl::Condition +{ + /** Representation. + */ + oslInterlockedCount m_nReferenceCount; + + /** Not implemented. + */ + SALHELPER_COPYCTOR_API(MonitorCondition); + +public: + /** Construction. + */ + inline MonitorCondition() SAL_THROW(()) : m_nReferenceCount (0) + { + Condition::set(); + } + + /** Destruction. + */ + inline ~MonitorCondition() SAL_THROW(()) + { + OSL_ASSERT(m_nReferenceCount == 0); + } + + /** Acquire or enter the monitor. + */ + inline void acquire() SAL_THROW(()) + { + if (osl_incrementInterlockedCount (&m_nReferenceCount) == 1) + { + Condition::reset(); + } + } + + /** Release or leave the monitor. + */ + inline void release() SAL_THROW(()) + { + if (osl_decrementInterlockedCount (&m_nReferenceCount) == 0) + { + Condition::set(); + } + } + + /** Wait until all references are released. + */ + inline void wait() SAL_THROW(()) + { + Condition::wait(); + } +}; + +//---------------------------------------------------------------------------- + +class QueuedReaderWriterMonitor : public salhelper::ReferenceObject +{ + /** Representation. + */ + typedef salhelper::Future<sal_Int32> future_type; + + salhelper::FutureQueue<sal_Int32> m_aQueue; + salhelper::MonitorCondition m_aMonitor; + + /** Not implemented. + */ + SALHELPER_COPYCTOR_API(QueuedReaderWriterMonitor); + +public: + /** Construction. + */ + inline QueuedReaderWriterMonitor() + { + // Insert the token. + m_aQueue.put(0); + } + + /** Acquire read access. + */ + inline void acquireReader() + { + // Obtain the token. + rtl::Reference<future_type> xFuture (m_aQueue.get()); + xFuture->get(); + + // Enter the monitor. + m_aMonitor.acquire(); + + // Push back the token. + m_aQueue.put(0); + } + + /** Release read access. + */ + inline void releaseReader() + { + // Leave the monitor. + m_aMonitor.release(); + } + + /** Acquire write access. + */ + inline void acquireWriter() + { + // Obtain the token. + rtl::Reference<future_type> xFuture (m_aQueue.get()); + xFuture->get(); + + // Wait until all readers have left. + m_aMonitor.wait(); + } + + /** Release write access. + */ + inline void releaseWriter() + { + // Push back the token. + m_aQueue.put(0); + } + +protected: + /** Destruction. + */ + virtual ~QueuedReaderWriterMonitor() + {} +}; + +//---------------------------------------------------------------------------- + +template<class monitor_type> +class ReaderGuard +{ + /** Representation. + */ + monitor_type *m_pMonitor; + + /** Not implemented. + */ + SALHELPER_COPYCTOR_API(ReaderGuard<monitor_type>); + +public: + /** Construction. Acquire monitor read access. + */ + inline ReaderGuard (monitor_type & rMonitor) : m_pMonitor (&rMonitor) + { + m_pMonitor->acquireReader(); + } + + /** Construction. Acquire monitor read access. + */ + inline ReaderGuard (monitor_type * pMonitor) : m_pMonitor (pMonitor) + { + OSL_PRECOND(m_pMonitor, "ReaderGuard::ReaderGuard(): No Monitor"); + m_pMonitor->acquireReader(); + } + + /** Destruction. Release monitor read access. + */ + inline ~ReaderGuard() + { + if (m_pMonitor) + m_pMonitor->releaseReader(); + } + + /** Release monitor read access. + */ + inline void clear() + { + if (m_pMonitor) + { + m_pMonitor->releaseReader(); + m_pMonitor = 0; + } + } +}; + +//---------------------------------------------------------------------------- + +typedef ReaderGuard<QueuedReaderWriterMonitor> QueuedReaderGuard; + +//---------------------------------------------------------------------------- + +template<class monitor_type> +class WriterGuard +{ + /** Representation. + */ + monitor_type *m_pMonitor; + + /** Not implemented. + */ + SALHELPER_COPYCTOR_API(WriterGuard<monitor_type>); + +public: + /** Construction. Acquire monitor write access. + */ + inline WriterGuard (monitor_type & rMonitor) : m_pMonitor (&rMonitor) + { + m_pMonitor->acquireWriter(); + } + + /** Construction. Acquire monitor write access. + */ + inline WriterGuard (monitor_type * pMonitor) : m_pMonitor (pMonitor) + { + OSL_PRECOND(m_pMonitor, "WriterGuard::WriterGuard(): No Monitor"); + m_pMonitor->acquireWriter(); + } + + /** Destruction. Release monitor write access. + */ + inline ~WriterGuard() + { + if (m_pMonitor) + m_pMonitor->releaseWriter(); + } + + /** Release monitor write access. + */ + inline void clear() + { + if (m_pMonitor) + { + m_pMonitor->releaseWriter(); + m_pMonitor = 0; + } + } +}; + +//---------------------------------------------------------------------------- + +typedef WriterGuard<QueuedReaderWriterMonitor> QueuedWriterGuard; + +//---------------------------------------------------------------------------- + +} // namespace salhelper + +#endif /* !_SALHELPER_MONITOR_HXX_ */ diff --git a/salhelper/inc/salhelper/queue.hxx b/salhelper/inc/salhelper/queue.hxx new file mode 100644 index 000000000000..f0daa8e9a904 --- /dev/null +++ b/salhelper/inc/salhelper/queue.hxx @@ -0,0 +1,174 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SALHELPER_QUEUE_HXX_ +#define _SALHELPER_QUEUE_HXX_ + +#include <sal/types.h> +#include <osl/diagnose.h> +#include <osl/mutex.hxx> +#ifndef _OSL_SEMAPHOR_HXX_ +#include <osl/semaphor.hxx> +#endif + +#ifndef __LIST__ +#include <list> +#endif + +namespace salhelper +{ + +//---------------------------------------------------------------------------- + +#ifndef SALHELPER_COPYCTOR_API +#define SALHELPER_COPYCTOR_API(C) C (const C&); C& operator= (const C&) +#endif + +//---------------------------------------------------------------------------- + +template<class element_type> +class QueueBase : protected std::list<element_type> +{ + /** Representation. + */ + osl::Mutex m_aMutex; + + /** Not implemented. + */ + SALHELPER_COPYCTOR_API(QueueBase<element_type>); + +public: + inline QueueBase() + {} + + inline ~QueueBase() + { + erase (this->begin(), this->end()); + } + + inline void put (const element_type& element) + { + osl::MutexGuard aGuard (m_aMutex); + push_back (element); + } + + inline element_type get() + { + element_type element; + + osl::MutexGuard aGuard (m_aMutex); + if (!this->empty()) + { + element = this->front(); + this->pop_front(); + } + + return (element); + } +}; + +//---------------------------------------------------------------------------- + +template<class element_type> +class Queue : protected QueueBase<element_type> +{ + /** Representation. + */ + osl::Semaphore m_aNotEmpty; + + /** Not implemented. + */ + SALHELPER_COPYCTOR_API(Queue<element_type>); + +public: + inline Queue() : m_aNotEmpty (static_cast< sal_uInt32 >(0)) + {} + + inline ~Queue() + {} + + inline void put (const element_type& element) + { + QueueBase<element_type>::put (element); + m_aNotEmpty.release(); + } + + inline element_type get() + { + element_type element; + + m_aNotEmpty.acquire(); + element = QueueBase<element_type>::get(); + + return (element); + } +}; + +//---------------------------------------------------------------------------- + +template<class element_type> +class BoundedQueue : protected Queue<element_type> +{ + /** Representation. + */ + osl::Semaphore m_aNotFull; + + /** Not implemented. + */ + SALHELPER_COPYCTOR_API(BoundedQueue<element_type>); + +public: + inline BoundedQueue (sal_uInt32 capacity) : m_aNotFull (capacity) + { + OSL_POSTCOND(capacity, "BoundedQueue:BoundedQueue(): no capacity"); + } + + inline ~BoundedQueue() + {} + + inline void put (const element_type& element) + { + m_aNotFull.acquire(); + Queue<element_type>::put (element); + } + + inline element_type get() + { + element_type element; + + element = Queue<element_type>::get(); + m_aNotFull.release(); + + return (element); + } +}; + +//---------------------------------------------------------------------------- + +} // namespace salhelper + +#endif /* !_SALHELPER_QUEUE_HXX_ */ diff --git a/salhelper/inc/salhelper/refobj.hxx b/salhelper/inc/salhelper/refobj.hxx new file mode 100644 index 000000000000..a1851eb84259 --- /dev/null +++ b/salhelper/inc/salhelper/refobj.hxx @@ -0,0 +1,110 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SALHELPER_REFOBJ_HXX_ +#define _SALHELPER_REFOBJ_HXX_ + +#include <sal/types.h> +#include <rtl/alloc.h> +#include <rtl/ref.hxx> +#include <osl/diagnose.h> +#include <osl/interlck.h> + +namespace salhelper +{ + +//---------------------------------------------------------------------------- + +class ReferenceObject : public rtl::IReference +{ + /** Representation. + */ + oslInterlockedCount m_nReferenceCount; + + /** Not implemented. + */ + ReferenceObject (const ReferenceObject&); + ReferenceObject& operator= (const ReferenceObject&); + +public: + /** Allocation. + */ + static void* operator new (size_t n) SAL_THROW(()) + { + return ::rtl_allocateMemory (n); + } + static void operator delete (void* p) SAL_THROW(()) + { + ::rtl_freeMemory (p); + } + static void* operator new (size_t, void* p) SAL_THROW(()) + { + return (p); + } + static void operator delete (void*, void*) SAL_THROW(()) + {} + +public: + /** Construction. + */ + inline ReferenceObject() SAL_THROW(()) : m_nReferenceCount (0) + {} + + + /** IReference. + */ + virtual oslInterlockedCount SAL_CALL acquire() SAL_THROW(()) + { + return ::osl_incrementInterlockedCount (&m_nReferenceCount); + } + + virtual oslInterlockedCount SAL_CALL release() SAL_THROW(()) + { + oslInterlockedCount result; + result = ::osl_decrementInterlockedCount (&m_nReferenceCount); + if (result == 0) + { + // Last reference released. + delete this; + } + return (result); + } + +protected: + /** Destruction. + */ + virtual ~ReferenceObject() SAL_THROW(()) + { + OSL_ASSERT(m_nReferenceCount == 0); + } +}; + +//---------------------------------------------------------------------------- + +} // namespace salhelper + +#endif /* !_SALHELPER_REFOBJ_HXX_ */ diff --git a/salhelper/inc/salhelper/simplereferenceobject.hxx b/salhelper/inc/salhelper/simplereferenceobject.hxx new file mode 100755 index 000000000000..4d2c60b733aa --- /dev/null +++ b/salhelper/inc/salhelper/simplereferenceobject.hxx @@ -0,0 +1,136 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SALHELPER_SIMPLEREFERENCEOBJECT_HXX_ +#define _SALHELPER_SIMPLEREFERENCEOBJECT_HXX_ + +#include "osl/interlck.h" +#include "sal/types.h" + +#ifndef INCLUDED_CSTDDEF +#include <cstddef> +#define INCLUDED_CSTDDEF +#endif +#ifndef INCLUDED_NEW +#include <new> +#define INCLUDED_NEW +#endif + +namespace salhelper { + +/** A simple base implementation for reference-counted objects. + + Classes that want to implement a reference-counting mechanism based on the + acquire()/release() interface should derive from this class. + + The reason to have class local operators new and delete here is technical. + Imagine a class D derived from SimpleReferenceObject, but implemented in + another shared library that happens to use different global operators new + and delete from those used in this shared library (which, sadly, seems to + be possible with shared libraries). Now, without the class local + operators new and delete here, a code sequence like "new D" would use the + global operator new as found in the other shared library, while the code + sequence "delete this" in release() would use the global operator delete + as found in this shared library---and these two operators would not be + guaranteed to match. + + There are no overloaded operators new and delete for placement new here, + because it is felt that the concept of placement new does not work well + with the concept of reference-counted objects; so it seems best to simply + leave those operators out. + + The same problem as with operators new and delete would also be there with + operators new[] and delete[]. But since arrays of reference-counted + objects are of no use, anyway, it seems best to simply declare and not + define (private) operators new[] and delete[]. + */ +class SimpleReferenceObject +{ +public: + inline SimpleReferenceObject() SAL_THROW(()): m_nCount(0) {} + + /** @ATTENTION + The results are undefined if, for any individual instance of + SimpleReferenceObject, the total number of calls to acquire() exceeds + the total number of calls to release() by a plattform dependent amount + (which, hopefully, is quite large). + */ + inline void acquire() SAL_THROW(()) + { osl_incrementInterlockedCount(&m_nCount); } + + inline void release() SAL_THROW(()) + { if (osl_decrementInterlockedCount(&m_nCount) == 0) delete this; } + + /** see general class documentation + */ + static void * operator new(std::size_t nSize) SAL_THROW((std::bad_alloc)); + + /** see general class documentation + */ + static void * operator new(std::size_t nSize, + std::nothrow_t const & rNothrow) + SAL_THROW(()); + + /** see general class documentation + */ + static void operator delete(void * pPtr) SAL_THROW(()); + + /** see general class documentation + */ + static void operator delete(void * pPtr, std::nothrow_t const & rNothrow) + SAL_THROW(()); + +protected: + virtual ~SimpleReferenceObject() SAL_THROW(()); + +private: + oslInterlockedCount m_nCount; + + /** not implemented + @internal + */ + SimpleReferenceObject(SimpleReferenceObject &); + + /** not implemented + @internal + */ + void operator =(SimpleReferenceObject); + + /** not implemented (see general class documentation) + @internal + */ + static void * operator new[](std::size_t); + + /** not implemented (see general class documentation) + @internal + */ + static void operator delete[](void * pPtr); +}; + +} + +#endif // _SALHELPER_SIMPLEREFERENCEOBJECT_HXX_ diff --git a/salhelper/inc/salhelper/singletonref.hxx b/salhelper/inc/salhelper/singletonref.hxx new file mode 100644 index 000000000000..9a62be5dfe92 --- /dev/null +++ b/salhelper/inc/salhelper/singletonref.hxx @@ -0,0 +1,210 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SALHELPER_SINGLETONREF_HXX_ +#define _SALHELPER_SINGLETONREF_HXX_ + +//_______________________________________________ +// includes + +#include <osl/mutex.hxx> +#include "rtl/instance.hxx" +#include "osl/diagnose.h" +#include "osl/getglobalmutex.hxx" + +//_______________________________________________ +// namespace + +namespace salhelper{ + +//_______________________________________________ +// definitions + +/** @short template for implementing singleton classes. + + @descr Such classes can be instanciated everytimes they + are needed. But the internal wrapped object will + be created one times only. Of course its used + resources are referenced one times only too. + This template hold it alive till the last + reference is gone. Further all operations + on this reference are threadsafe. Only + calls directly to the internal object (which modify + its state) must be made threadsafe by the object itself + or from outside. + + @attention To prevent the code against race conditions, its not + allowed to start operations inside the ctor + of the internal wrapped object - especialy operations + which needs a reference to the same singleton too. + + The only chance to supress such strange constellations + is a lazy-init mechanism. + + <ul> + <li>a) The singleton class can provide a special init() + method, which must be called as first after creation.</li> + <li>b) The singleton class can call a special impl_init() + method implicit for every called interface method.</li> + </ul> + + Note further that this singleton pattern can work only, if + all user of such singleton are located inside the same library! + Because static values cant be exported - e.g. from windows libraries. + */ +template< class SingletonClass > +class SingletonRef +{ + //------------------------------------------- + // member + + private : + + /** @short pointer to the internal wrapped singleton. */ + static SingletonClass* m_pInstance; + + /** @short ref count, which regulate creation and removing of m_pInstance. */ + static sal_Int32 m_nRef; + + //------------------------------------------- + // interface + + public : + + //--------------------------------------- + + /** @short standard ctor. + + @descr The internal wrapped object is created only, + if its ref count was 0. Otherwhise this method + does nothing ... except increasing of the internal + ref count! + */ + SingletonRef() + { + // GLOBAL SAFE -> + ::osl::MutexGuard aLock(SingletonRef::ownStaticLock()); + + // must be increased before(!) the check is done. + // Otherwhise this check can fail inside the same thread ... + ++m_nRef; + if (m_nRef == 1) + m_pInstance = new SingletonClass(); + + OSL_ENSURE(m_nRef>0 && m_pInstance, "Race? Ref count of singleton >0, but instance is NULL!"); + // <- GLOBAL SAFE + } + + //--------------------------------------- + + /** @short standard dtor. + + @descr The internal wrapped object is removed only, + if its ref count wil be 0. Otherwhise this method + does nothing ... except decreasing of the internal + ref count! + */ + ~SingletonRef() + { + // GLOBAL SAFE -> + ::osl::MutexGuard aLock(SingletonRef::ownStaticLock()); + + // must be decreased before(!) the check is done. + // Otherwhise this check can fail inside the same thread ... + --m_nRef; + if (m_nRef == 0) + { + delete m_pInstance; + m_pInstance = 0; + } + // <- GLOBAL SAFE + } + + //--------------------------------------- + + /** @short Allows rSingle->someBodyOp(). + */ + SingletonClass* operator->() const + { + // GLOBAL SAFE -> + ::osl::MutexGuard aLock(SingletonRef::ownStaticLock()); + return m_pInstance; + // <- GLOBAL SAFE + } + + //--------------------------------------- + + /** @short Allows (*rSingle).someBodyOp(). + */ + SingletonClass& operator*() const + { + // GLOBAL SAFE -> + ::osl::MutexGuard aLock(SingletonRef::ownStaticLock()); + return *m_pInstance; + // <- GLOBAL SAFE + } + + //------------------------------------------- + // helper + + private : + + //--------------------------------------- + + /** @short creates an own mutex for guarding static contents. + + @descr The global mutex the osl library is used one times + only to create an own static mutex, which can be used + next time to guard own static member operations. + */ + struct SingletonLockInit + { + ::osl::Mutex* operator()() + { + static ::osl::Mutex aInstance; + return &aInstance; + } + }; + + ::osl::Mutex& ownStaticLock() const + { + return *rtl_Instance< ::osl::Mutex, + SingletonLockInit, + ::osl::MutexGuard, + ::osl::GetGlobalMutex >::create(SingletonLockInit(), ::osl::GetGlobalMutex()); + } +}; + +template< class SingletonClass > +SingletonClass* SingletonRef< SingletonClass >::m_pInstance = 0; + +template< class SingletonClass > +sal_Int32 SingletonRef< SingletonClass >::m_nRef = 0; + +} // namespace salhelper + +#endif // _SALHELPER_SINGLETONREF_HXX_ |