diff --git a/Makefile b/Makefile index c10fe7ddf53b1e66233abd358c10551e573bc2be..7cedfd8791e9fd2b014c87a3e0e41e09fccf8453 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,26 @@ NAME_SRV = ds-libera-srv -CXXFLAGS = -I i-tech/server/include -I i-tech/cspi/include -I i-tech/driver/include/ -CXXFLAGS += -DEBPP -LDFLAGS = -L i-tech/server/lib -lclient + + +ITECHINCLUDES = -I i-tech/server/include -I i-tech/cspi/include -I i-tech/driver/include/ +ITECHLIBS = -L i-tech/server/lib -lclient + +#- export floating point device attributes as DevFloat (instead of DevDouble) +USE_FLOAT_ATTRIBUTES = 0 + +#- use cspi SA events (not recommended!) +USE_SA_EVENTS = 0 + +ifeq ($(USE_FLOAT_FP_DATA),1) +CXXFLAGS += -D_USE_FLOAT_FP_DATA_ +endif + +ifeq ($(USE_SA_EVENTS),1) +CXXFLAGS += -D_USE_SA_EVENTS_ +endif + +CXXFLAGS = $(ITECHINCLUDES) -D_REENTRANT -fno-enforce-eh-specs -DEBPP +LDFLAGS = -lpthread $(ITECHLIBS) + +CXXFLAGS += -fpermissive + include ../makefiles/Make-9.3.3.in diff --git a/src/BPM.h b/src/BPM.h index 09f0241c362a30b4f1013053c9b6a89b68ca47ad..441ed9d7cadca00d05d929969671ed9200d260f6 100644 --- a/src/BPM.h +++ b/src/BPM.h @@ -39,7 +39,7 @@ #include "BPMBuffer.h" #include "BPMSensors.h" #include "LiberaEvents.h" -#include "threading/Task.h" +#include "Task.h" // ============================================================================ // DEFINEs diff --git a/src/BPMData.h b/src/BPMData.h index 2fdd846b8b7b6ed1531181b3fac46dcdc4e6e8fd..d8734827a4fac2ce6ec23868c4814ae36215f73c 100644 --- a/src/BPMData.h +++ b/src/BPMData.h @@ -33,7 +33,7 @@ // ============================================================================ // DEPENDENCIES // ============================================================================ -#include "threading/SharedObject.h" +#include "SharedObject.h" #include "BPMBuffer.h" #if defined(_EMBEDDED_DEVICE_) && defined(_USE_ARM_OPTIMIZATION_) @@ -488,7 +488,7 @@ class ADCData : private bpm::SharedObject public: - typedef Buffer<short> Buffer; + typedef Buffer<short> BufferADC; /** * Ctor @@ -508,10 +508,10 @@ public: /** * The data buffers accessors */ - const ADCData::Buffer& a (void) const; - const ADCData::Buffer& b (void) const; - const ADCData::Buffer& c (void) const; - const ADCData::Buffer& d (void) const; + const ADCData::BufferADC& a (void) const; + const ADCData::BufferADC& b (void) const; + const ADCData::BufferADC& c (void) const; + const ADCData::BufferADC& d (void) const; /** * The data timestamp @@ -541,10 +541,10 @@ private: size_t current_buffers_depth () const; - ADCData::Buffer a_; - ADCData::Buffer b_; - ADCData::Buffer c_; - ADCData::Buffer d_; + ADCData::BufferADC a_; + ADCData::BufferADC b_; + ADCData::BufferADC c_; + ADCData::BufferADC d_; struct timespec timestamp_; diff --git a/src/BPMData.i b/src/BPMData.i index 7eb2eb5d62c59f5a3326f0a4951e3833cd983154..dc4c137e32f8a010ab585fc3e310d68e710e3987 100644 --- a/src/BPMData.i +++ b/src/BPMData.i @@ -689,7 +689,7 @@ INLINE_IMPL void ADCData::release (void) // ============================================================================ // ADCData::a // ============================================================================ -INLINE_IMPL const ADCData::Buffer& ADCData::a (void) const +INLINE_IMPL const ADCData::BufferADC& ADCData::a (void) const { return this->a_; } @@ -697,7 +697,7 @@ INLINE_IMPL const ADCData::Buffer& ADCData::a (void) const // ============================================================================ // ADCData::b // ============================================================================ -INLINE_IMPL const ADCData::Buffer& ADCData::b (void) const +INLINE_IMPL const ADCData::BufferADC& ADCData::b (void) const { return this->b_; } @@ -705,7 +705,7 @@ INLINE_IMPL const ADCData::Buffer& ADCData::b (void) const // ============================================================================ // ADCData::c // ============================================================================ -INLINE_IMPL const ADCData::Buffer& ADCData::c (void) const +INLINE_IMPL const ADCData::BufferADC& ADCData::c (void) const { return this->c_; } @@ -713,7 +713,7 @@ INLINE_IMPL const ADCData::Buffer& ADCData::c (void) const // ============================================================================ // ADCData::d // ============================================================================ -INLINE_IMPL const ADCData::Buffer& ADCData::d (void) const +INLINE_IMPL const ADCData::BufferADC& ADCData::d (void) const { return this->d_; } diff --git a/src/Condition.h b/src/Condition.h index 3b39232b57bef1a0ac79d3f91305128fa9eec2f2..321edec9c02b923a455caa6de72b73bca6d6c4af 100644 --- a/src/Condition.h +++ b/src/Condition.h @@ -33,7 +33,7 @@ // ============================================================================ // DEPENDENCIES // ============================================================================ -#include "threading/Implementation.h" +#include "Implementation.h" // ---------------------------------------------------------------------------- // Implementation-specific header file. @@ -124,7 +124,7 @@ private: } // namespace bpm #if defined (__INLINE_IMPL__) -# include <threading/impl/PosixConditionImpl.i> +# include <PosixConditionImpl.i> #endif #endif //- _BPM_CONDITION_H_ diff --git a/src/Implementation.h b/src/Implementation.h index af050779e83da00c4778069083d4f4eda7c0a58c..4a4ac05b47659b4295ea28d8b983ef33bf553c23 100644 --- a/src/Implementation.h +++ b/src/Implementation.h @@ -34,7 +34,7 @@ // DEPENDENCIES // ============================================================================ #include "CommonHeader.h" -#include "threading/impl/PosixThreadingImpl.h" +#include "PosixThreadingImpl.h" // ============================================================================ // MISC DEFINEs diff --git a/src/InnerAppender.h b/src/InnerAppender.h index 085daa5bad45c49fd54a2a33e0add72bd48f657b..8a7f132bcd1a06dc2b59c3458ddcf29370008e52 100644 --- a/src/InnerAppender.h +++ b/src/InnerAppender.h @@ -18,7 +18,7 @@ // DEPENDENCIES // ============================================================================ #include <deque> -#include <threading/Mutex.h> +#include <Mutex.h> #include <tango.h> namespace Libera_ns diff --git a/src/LiberaClass.cpp b/src/LiberaClass.cpp index c16966b67e5bf35a2bea940fffa5b19a047ee459..2d93e6b60458c83ba8703079d09b63e2eb465fd9 100644 --- a/src/LiberaClass.cpp +++ b/src/LiberaClass.cpp @@ -22,7 +22,7 @@ static const char *RCSfile = "$RCSfile: LiberaClass.cpp,v $"; // Revision 1.4.2.30.2.1 2008/05/25 13:21:42 nleclercq // Enhanced embedded device support // Reorganized src tree -// Complete rewrite of threading support (code extracted from NL & JM YAT lib) +// Complete rewrite of support (code extracted from NL & JM YAT lib) // Add DD buffer freezing support for embedded device // Added BPMSensors class (CPU & Memory uage) // Misc. minor changes diff --git a/src/LiberaEvents.h b/src/LiberaEvents.h index a27d27046a1e0e3d3135d08b7767b0a056d15c28..0d703efb66d4f4921aeadf6db67e7b3da5e003bd 100644 --- a/src/LiberaEvents.h +++ b/src/LiberaEvents.h @@ -34,7 +34,7 @@ // ============================================================================ // DEPENDENCIES // ============================================================================ -#include "threading/Thread.h" +#include "Thread.h" namespace bpm { diff --git a/src/Message.cpp b/src/Message.cpp index cdc365dd3123f5bfb2c9793ab7c5211290bf539e..fe75f5c216017d2f21b6538c8a1fbf55fa2b20fa 100644 --- a/src/Message.cpp +++ b/src/Message.cpp @@ -32,10 +32,10 @@ // ============================================================================ #include <math.h> #include "CommonHeader.h" -#include "threading/Message.h" +#include "Message.h" #if !defined (__INLINE_IMPL__) -# include "threading/Message.i" +# include "Message.i" #endif // __INLINE_IMPL__ namespace bpm diff --git a/src/Message.h b/src/Message.h index 793a3f43b5d84507a3aff74d6b0a62a5b49520e5..ca601362fd362f0e44dd83c153a4ec4e69184dfd 100644 --- a/src/Message.h +++ b/src/Message.h @@ -33,11 +33,11 @@ // ============================================================================ // DEPENDENCIES // ============================================================================ -#include "threading/Mutex.h" -#include "threading/Condition.h" -#include "threading/Semaphore.h" -#include "threading/SharedObject.h" -#include "threading/GenericContainer.h" +#include "Mutex.h" +#include "Condition.h" +#include "Semaphore.h" +#include "SharedObject.h" +#include "GenericContainer.h" // ============================================================================ // CONSTs @@ -326,7 +326,7 @@ private: } // namespace bpm #if defined (__INLINE_IMPL__) -# include "threading/Message.i" +# include "Message.i" #endif #endif // _BPM_MSG_H_ diff --git a/src/threading/Message.i b/src/Message.i similarity index 100% rename from src/threading/Message.i rename to src/Message.i diff --git a/src/MessageQ.cpp b/src/MessageQ.cpp index 38f0c837fb758c5cf77d9634dda44a8ebe31139d..bf811f5b2f0fa0c83f2a0610ff19db14eec7f5e2 100644 --- a/src/MessageQ.cpp +++ b/src/MessageQ.cpp @@ -31,10 +31,10 @@ // DEPENDENCIES // ============================================================================ #include "CommonHeader.h" -#include "threading/MessageQ.h" +#include "MessageQ.h" #if !defined (__INLINE_IMPL__) -# include "threading/MessageQ.i" +# include "/MessageQ.i" #endif // __INLINE_IMPL__ namespace bpm diff --git a/src/MessageQ.h b/src/MessageQ.h index ee8af1d8f7aab0b6bd4fa49d2267158a0834823f..1bb261300bc7b6728d63516b034e566f80e3476e 100644 --- a/src/MessageQ.h +++ b/src/MessageQ.h @@ -35,7 +35,7 @@ // ============================================================================ #include <list> #include "CommonHeader.h" -#include "threading/Message.h" +#include "Message.h" // ============================================================================ // CONSTs @@ -194,7 +194,7 @@ private: } // namespace bpm #if defined (__INLINE_IMPL__) -# include "threading/MessageQ.i" +# include "MessageQ.i" #endif // __INLINE_IMPL__ #endif // _BPM_MSGQ_H_ diff --git a/src/threading/MessageQ.i b/src/MessageQ.i similarity index 100% rename from src/threading/MessageQ.i rename to src/MessageQ.i diff --git a/src/Mutex.h b/src/Mutex.h index b1fd465d4e30697e324d930a67f92d183f4225d0..23b072a6a271c209eb4e0d8780a04459e153098a 100644 --- a/src/Mutex.h +++ b/src/Mutex.h @@ -33,8 +33,8 @@ // ============================================================================ // DEPENDENCIES // ============================================================================ -#include "threading/Utilities.h" -#include "threading/Implementation.h" +#include "Utilities.h" +#include "Implementation.h" // ============================================================================ // Implementation-specific header file. @@ -231,7 +231,7 @@ typedef AutoMutex<Mutex> MutexLock; } // namespace bpm #if defined (__INLINE_IMPL__) -# include "threading/impl/PosixMutexImpl.i" +# include "PosixMutexImpl.i" #endif #endif //- _BPM_MUTEX_H_ diff --git a/src/PosixThreadingImpl.cpp b/src/PosixThreadingImpl.cpp index 9475a7887d83c1799ff6eb2a12c3b314b067accd..fd813f9ec89f461a03bcf8c65577baec07db59da 100644 --- a/src/PosixThreadingImpl.cpp +++ b/src/PosixThreadingImpl.cpp @@ -33,17 +33,17 @@ #include <errno.h> #include <sys/time.h> #include "CommonHeader.h" -#include "threading/Utilities.h" -#include "threading/Mutex.h" -#include "threading/Condition.h" -#include "threading/Semaphore.h" -#include "threading/Thread.h" +#include "Utilities.h" +#include "Mutex.h" +#include "Condition.h" +#include "Semaphore.h" +#include "Thread.h" #if ! defined (__INLINE_IMPL__) -# include "threading/impl/PosixMutexImpl.i" -# include "threading/impl/PosixConditionImpl.i" -# include "threading/impl/PosixSemaphoreImpl.i" -# include "threading/impl/PosixThreadImpl.i" +# include "/PosixMutexImpl.i" +# include "/PosixConditionImpl.i" +# include "/PosixSemaphoreImpl.i" +# include "/PosixThreadImpl.i" #endif // ============================================================================ diff --git a/src/Semaphore.h b/src/Semaphore.h index 32975eed7aca229d90e52922a33183850e103918..503190c0da868f7ec970d66e05389541940a2528 100644 --- a/src/Semaphore.h +++ b/src/Semaphore.h @@ -33,9 +33,9 @@ // ============================================================================ // DEPENDENCIES // ============================================================================ -#include "threading/Implementation.h" -#include "threading/Mutex.h" -#include "threading/Condition.h" +#include "Implementation.h" +#include "Mutex.h" +#include "Condition.h" // ============================================================================ // Implementation-specific header file. @@ -136,7 +136,7 @@ private: } // namespace bpm #if defined (__INLINE_IMPL__) -# include "threading/impl/PosixSemaphoreImpl.i" +# include "PosixSemaphoreImpl.i" #endif #endif //- _BPM_SEMAPHORE_H_ diff --git a/src/SharedObject.cpp b/src/SharedObject.cpp index 5ebee01cc55c13c9a460e573e3322667f3dcd645..a04829497e668587cfe873a681e6839f2d1b0fb8 100644 --- a/src/SharedObject.cpp +++ b/src/SharedObject.cpp @@ -30,10 +30,10 @@ // ============================================================================ // DEPENDENCIES // ============================================================================ -#include "threading/SharedObject.h" +#include "SharedObject.h" #if !defined (__INLINE_IMPL__) -# include "threading/SharedObject.i" +# include "SharedObject.i" #endif namespace bpm diff --git a/src/SharedObject.h b/src/SharedObject.h index 013366a403611e2aa754c405bb3976ba2a098fbf..1b63086cd7feef1d7c70821a32d926a4ad2d21cb 100644 --- a/src/SharedObject.h +++ b/src/SharedObject.h @@ -34,7 +34,7 @@ // DEPENDENCIES // ============================================================================ #include "CommonHeader.h" -#include "threading/Mutex.h" +#include "Mutex.h" namespace bpm { @@ -94,7 +94,7 @@ private: } // namespace bpm #if defined (__INLINE_IMPL__) -# include "threading/SharedObject.i" +# include "SharedObject.i" #endif #endif // _SHARED_OBJECT_H_ diff --git a/src/threading/SharedObject.i b/src/SharedObject.i similarity index 100% rename from src/threading/SharedObject.i rename to src/SharedObject.i diff --git a/src/Task.cpp b/src/Task.cpp index f4d81fcc59b272e8b0bb24ecf177cbe0c2010545..26228769261a33813806210c174168cf9d552a6f 100644 --- a/src/Task.cpp +++ b/src/Task.cpp @@ -31,10 +31,10 @@ // DEPENDENCIES // ============================================================================ #include "CommonHeader.h" -#include "threading/Task.h" +#include "Task.h" #if !defined (__INLINE_IMPL__) -# include "threading/Task.i" +# include "Task.i" #endif namespace bpm diff --git a/src/Task.h b/src/Task.h index 4eafde9992efbe59f13a235fb90574c38ce8c81e..17a0407c8a68cbda78b1f1ac11ae181e99b4ca9b 100644 --- a/src/Task.h +++ b/src/Task.h @@ -33,8 +33,8 @@ // ============================================================================ // DEPENDENCIES // ============================================================================ -#include "threading/Thread.h" -#include "threading/MessageQ.h" +#include "Thread.h" +#include "MessageQ.h" // ============================================================================ // CONSTs @@ -199,7 +199,7 @@ private: } // namespace #if defined (__INLINE_IMPL__) -# include <threading/Task.i> +# include <Task.i> #endif #endif // _BPM_TASK_H_ diff --git a/src/threading/Task.i b/src/Task.i similarity index 100% rename from src/threading/Task.i rename to src/Task.i diff --git a/src/Thread.h b/src/Thread.h index 7d9287c627cec0ea62ca1daecac774d6104c12c9..ccf20a9885a70169ddc5e6f05fdc7be494cba837 100644 --- a/src/Thread.h +++ b/src/Thread.h @@ -33,7 +33,7 @@ // ---------------------------------------------------------------------------- // DEPENDENCIES // ---------------------------------------------------------------------------- -#include "threading/Mutex.h" +#include "Mutex.h" // ---------------------------------------------------------------------------- // Implementation-specific header file. @@ -201,7 +201,7 @@ private: } // namespace bpm #if defined (__INLINE_IMPL__) -# include "threading/impl/PosixThreadImpl.i" +# include "PosixThreadImpl.i" #endif #endif //- _BPM_THREAD_H_ diff --git a/src/Utilities.h b/src/Utilities.h index 8624e49694e2bb9f622b4518aeea7ebca72e3ac3..9693b9e5400b2549836b4f946fc77a0692c40107 100644 --- a/src/Utilities.h +++ b/src/Utilities.h @@ -34,7 +34,7 @@ // ============================================================================ // DEPENDENCIES // ============================================================================ -#include "threading/Implementation.h" +#include "Implementation.h" // ============================================================================ // CONSTs @@ -49,7 +49,7 @@ namespace bpm { typedef unsigned long ThreadUID; // ============================================================================ -//! The BPM threading utilities +//! The BPM utilities // ============================================================================ class ThreadingUtilities { diff --git a/src/threading/Condition.h b/src/threading/Condition.h deleted file mode 100644 index 3b39232b57bef1a0ac79d3f91305128fa9eec2f2..0000000000000000000000000000000000000000 --- a/src/threading/Condition.h +++ /dev/null @@ -1,130 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -#ifndef _BPM_CONDITION_H_ -#define _BPM_CONDITION_H_ - -// ============================================================================ -// DEPENDENCIES -// ============================================================================ -#include "threading/Implementation.h" - -// ---------------------------------------------------------------------------- -// Implementation-specific header file. -// ---------------------------------------------------------------------------- -#if ! defined(__CONDITION_IMPLEMENTATION) -# error "implementation header file incomplete [no condition implementation]" -#endif - -namespace bpm { - -// ---------------------------------------------------------------------------- -// FORWARD DECL -// ---------------------------------------------------------------------------- -class Mutex; - -// ---------------------------------------------------------------------------- -//! \class Condition -//! \brief The BPM Condition variable class -//! -//! The Windows implementation is based on D.C.Schmidt & Al solution describes -//! in the following article: http://www.cs.wustl.edu/~schmidt/win32-cv-1.html -//! -//! Under Linux (and any other \c POSIX platforms), the code relies on the local -//! \c pthread implementation. -//! -//! \remarks -//! While its destructor is virtual, this class is not supposed to be derived.\n -//! Be sure to clearly understand the internal behaviour before trying to do so. -// ---------------------------------------------------------------------------- -class Condition -{ -public: - //! Constructor. - //! - //! Each condition must be associated to a mutex that must be hold while - //! evaluating the condition. It means that \a external_mutex must be locked - //! prior to any to call to the Condition interface. See \link - //! http://www.cs.wustl.edu/~schmidt/win32-cv-1.html D.C.Schmidt and I.Pyarali - //! \endlink article for details. - Condition (bpm::Mutex& external_mutex); - - //! Destructor. - //! - //! While this destructor is virtual, this class is not supposed to be derived. - //! Be sure to understand the internal behaviour before trying to do so. - virtual ~Condition (void); - - //! Wait until the condition is either \link Condition::signal signaled\endlink - //! or \link Condition::broadcast broadcasted\endlink by another thread. - //! - //! The associated \a external_mutex <b>must be locked</b> by the calling thread. - void wait (void); - - //! Wait for the condition to be \link Condition::signal signaled\endlink - //! or \link Condition::broadcast broadcasted\endlink by another thread. - //! Returns \c false in case the specified timeout expired before the condition - //! was notified. Returns \c true otherwise. - //! - //! The associated \a external_mutex <b>must be locked</b> by the calling thread. - //! - //! \param tmo_msecs The timeout in milliseconds - //! \return \c false [timeout expired] or \c true [condition notified] - bool timed_wait (unsigned long tmo_msecs); - - //! Signals the condition by notifying \b one of the waiting threads. - //! - //! The associated \a external_mutex <b>must be locked</b> by the calling thread. - void signal (void); - - //! Broadcasts the condition by notifying \b all waiting threads. - //! - //! The associated \a external_mutex <b>must be locked</b> by the calling thread. - void broadcast (void); - -private: - //! The so called "external mutex" (see D.Schmidt's article) - Mutex & m_external_lock; - - //! Not implemented private member - Condition (const Condition&); - //! Not implemented private member - Condition & operator= (const Condition&); - - //! hidden/abstract platform specific implementation - __CONDITION_IMPLEMENTATION; -}; - -} // namespace bpm - -#if defined (__INLINE_IMPL__) -# include <threading/impl/PosixConditionImpl.i> -#endif - -#endif //- _BPM_CONDITION_H_ diff --git a/src/threading/GenericContainer.h b/src/threading/GenericContainer.h deleted file mode 100644 index 35288f4e20db5bfc9feab96a3e89d4aa1040c5ea..0000000000000000000000000000000000000000 --- a/src/threading/GenericContainer.h +++ /dev/null @@ -1,155 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -#ifndef _GENERIC_CONTAINER_H_ -#define _GENERIC_CONTAINER_H_ - -#include "CommonHeader.h" - -namespace bpm -{ - -// ============================================================================ -// class: Container -// ============================================================================ -class Container -{ -public: - Container () - { - //- noop - }; - - virtual ~Container () - { - //- noop - }; -}; - -// ============================================================================ -// template class: GenericContainer - class T must have a copy ctor -// ============================================================================ -template <typename T> -class GenericContainer : public Container -{ -public: - - //- ctor - GenericContainer (T* _msg_data, bool _ownership = true) - : ptr_(_msg_data), own_(_ownership) - { - //- noop - } - - //- ctor - GenericContainer (const T& _data) - : ptr_(0), own_(true) - { - try - { - this->ptr_ = new T(_data); - if (this->ptr_ == 0) - throw std::bad_alloc(); - } - catch (const std::bad_alloc&) - { - this->ptr_ = 0; - Tango::Except::throw_exception (_CPTC("OUT_OF_MEMORY"), - _CPTC("memory allocation failed"), - _CPTC("GenericContainer:GenericContainer")); - } - } - - //- dtor - virtual ~GenericContainer () - { - if (own_) - delete this->ptr_; - } - - //- returns content and optionaly transfers ownership to caller - T * content (bool transfer_ownership) - { - T * tmp = this->ptr_; - if (transfer_ownership) - { - this->own_ = false; - this->ptr_ = 0; - } - return tmp; - } - - //- returns content - T & content () - { - return *(this->ptr_); - } - -private: - //- actual container content - T * ptr_; - bool own_; -}; - - -// ============================================================================ -// template function -// ============================================================================ -template <typename T> T * extract_data (Container * _c, - bool _transfer_ownership = true) - throw (Tango::DevFailed) -{ - GenericContainer<T> * gc = 0; - - try - { - gc = dynamic_cast<GenericContainer<T>*>(_c); - if (gc == 0) - { - Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"), - _CPTC("could not extract data from Container [unexpected content]"), - _CPTC("dettach_data")); - } - } - catch (const std::bad_cast&) - { - Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"), - _CPTC("could not extract data from Container [unexpected content]"), - _CPTC("dettach_data")); - } - - return gc->content(_transfer_ownership); -} - -} // namespace bpm - -#endif // _GENERIC_CONTAINER_H_ - - - diff --git a/src/threading/Implementation.h b/src/threading/Implementation.h deleted file mode 100644 index af050779e83da00c4778069083d4f4eda7c0a58c..0000000000000000000000000000000000000000 --- a/src/threading/Implementation.h +++ /dev/null @@ -1,45 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -#ifndef _BPM_THREADING_IMPL_H_ -#define _BPM_THREADING_IMPL_H_ - -// ============================================================================ -// DEPENDENCIES -// ============================================================================ -#include "CommonHeader.h" -#include "threading/impl/PosixThreadingImpl.h" - -// ============================================================================ -// MISC DEFINEs -// ============================================================================ -#define kINFINITE_WAIT 0 -#define DUMP_THREAD_UID std::hex << yat::ThreadingUtilities::self() << std::dec - -#endif //- _BPM_THREADING_IMPL_H_ diff --git a/src/threading/Message.cpp b/src/threading/Message.cpp deleted file mode 100644 index c6305788963edb13754d7675ed9465ea4967110e..0000000000000000000000000000000000000000 --- a/src/threading/Message.cpp +++ /dev/null @@ -1,210 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -// ============================================================================ -// DEPENDENCIES -// ============================================================================ -#include <math.h> -#include "CommonHeader.h" -#include "threading/Message.h" - -#if !defined (__INLINE_IMPL__) -# include "threading/Message.i" -#endif // __INLINE_IMPL__ - -namespace bpm -{ - -// ============================================================================ -// Message::allocate -// ============================================================================ -Message * Message::allocate (size_t _msg_type, size_t _msg_priority, bool _waitable) - throw (Tango::DevFailed) -{ - bpm::Message * msg = 0; - - try - { - msg = new bpm::Message (_msg_type, _msg_priority, _waitable); - if (msg == 0) - throw std::bad_alloc(); - } - catch (const std::bad_alloc&) - { - Tango::Except::throw_exception(_CPTC("OUT_OF_MEMORY"), - _CPTC("Message allocation failed"), - _CPTC("Message::allocate")); - } - catch (...) - { - Tango::Except::throw_exception(_CPTC("UNKNOWN_ERROR"), - _CPTC("Message allocation failed [unknown exception caught]"), - _CPTC("Message::allocate")); - } - - return msg; -} - -// ============================================================================ -// Message::Message -// ============================================================================ -Message::Message (CSPI_EVENT * e, size_t p, bool w) - : SharedObject (), - type_ (CSPI_USER), - priority_ (p), - cspi_data_ (e->hdr.param), - user_data_ (e->user_data), - msg_data_ (0), - cond_ (0), - has_waiter_ (false), - has_error_ (false) -{ - switch (e->hdr.id) - { - case CSPI_EVENT_USER: - this->type_ = CSPI_USER; - break; - case CSPI_EVENT_OVERFLOW: - switch (e->hdr.param) - { - case CSPI_OVERFLOW_DD_FPGA: - this->type_ = CSPI_DD_FPGA_OVERFLOW; - break; - case CSPI_OVERFLOW_SA_FPGA: - this->type_ = CSPI_SA_FPGA_OVERFLOW; - break; - case CSPI_OVERFLOW_SA_DRV: - this->type_ = CSPI_SA_DRVR_OVERFLOW; - break; - } - break; - case CSPI_EVENT_CFG: - this->type_ = CSPI_CONFIG_CHANGE; - break; - case CSPI_EVENT_SA: - this->type_ = CSPI_SA; - break; - case CSPI_EVENT_INTERLOCK: - this->type_ = CSPI_INTERLOCK; - break; - case CSPI_EVENT_PM: - this->type_ = CSPI_PM; - break; - case CSPI_EVENT_FA: - this->type_ = CSPI_FA; - break; - case CSPI_EVENT_TRIGGET: - this->type_ = CSPI_TRIGGET; - break; - case CSPI_EVENT_TRIGSET: - this->type_ = CSPI_TRIGSET; - break; - } - - if (w) - this->make_waitable(); -} - -// ============================================================================ -// Message::Message -// ============================================================================ -Message::Message (size_t t, size_t p, bool _w) - : SharedObject (), - type_ (t), - priority_ (p), - cspi_data_ (0), - user_data_ (0), - msg_data_ (0), - cond_ (0), - has_waiter_ (false), - has_error_ (false), - processed_ (false) -{ - if (_w) - this->make_waitable(); -} - -// ============================================================================ -// Message::~Message -// ============================================================================ -Message::~Message () -{ - //-note: exception_ contains some Tango::DevError which itself - //-note: contains CORBA::string_member which releases the - //-note: associated memory (i.e. char*) - - if (this->msg_data_) - { - delete this->msg_data_; - this->msg_data_ = 0; - } - - DEBUG_ASSERT(this->processed_ ? true : (this->has_waiter_ ? false : true)); - - if (this->cond_) - { - if (! this->processed_) - { - AutoMutex<Mutex> guard(this->lock_); - this->cond_->broadcast(); - } - delete this->cond_; - } -} - -// ============================================================================ -// Message::make_waitable -// ============================================================================ -void Message::make_waitable (void) - throw (Tango::DevFailed) -{ - if (this->cond_) - return; - - try - { - this->cond_ = new Condition(this->lock_); - if (this->cond_ == 0) - throw std::bad_alloc(); - } - catch (const std::bad_alloc&) - { - Tango::Except::throw_exception(_CPTC("MEMORY_ERROR"), - _CPTC("memory allocation failed"), - _CPTC("Message::make_waitable")); - } - catch (...) - { - Tango::Except::throw_exception(_CPTC("UNKNOWN_ERROR"), - _CPTC("memory allocation failed"), - _CPTC("Message::make_waitable")); - } -} - -} // namespace bpm diff --git a/src/threading/Message.h b/src/threading/Message.h deleted file mode 100644 index 266a127e4fec26b826e37b1670e503605f7b8da5..0000000000000000000000000000000000000000 --- a/src/threading/Message.h +++ /dev/null @@ -1,331 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -#ifndef _BPM_MSG_H_ -#define _BPM_MSG_H_ - -// ============================================================================ -// DEPENDENCIES -// ============================================================================ -#include "threading/Mutex.h" -#include "threading/Condition.h" -#include "threading/Semaphore.h" -#include "threading/SharedObject.h" -#include "threading/GenericContainer.h" - -// ============================================================================ -// CONSTs -// ============================================================================ -#define HIGHEST_MSG_PRIORITY 0xFFFF -#define LOWEST_MSG_PRIORITY 0 -#define INIT_MSG_PRIORITY HIGHEST_MSG_PRIORITY -#define EXIT_MSG_PRIORITY HIGHEST_MSG_PRIORITY -#define MAX_USER_PRIORITY (HIGHEST_MSG_PRIORITY - 20) -#define DEFAULT_MSG_PRIORITY LOWEST_MSG_PRIORITY -//----------------------------------------------------------------------------- - -namespace bpm -{ - -// ============================================================================ -// enum: MessageType -// ============================================================================ -typedef enum -{ - //-------------------- - CSPI_USER = 0, - CSPI_DD_FPGA_OVERFLOW, - CSPI_SA_FPGA_OVERFLOW, - CSPI_SA_DRVR_OVERFLOW, - CSPI_CONFIG_CHANGE, - CSPI_SA, - CSPI_INTERLOCK, - CSPI_PM, - CSPI_FA, - CSPI_TRIGGET, - CSPI_TRIGSET, - //-------------------- - TASK_INIT, - TASK_TIMEOUT, - TASK_PERIODIC, - TASK_EXIT, - //-------------------- - FIRST_USER_MSG = 1000 -} MessageType; - -// ============================================================================ -// struct: Message -// ============================================================================ -class Message : private SharedObject -{ - friend class Task; - friend class Thread; - -public: - - //--------------------------------------------- - // Message::factory - //--------------------------------------------- - static Message * allocate (size_t msg_type, - size_t msg_priority = DEFAULT_MSG_PRIORITY, - bool waitable = false) - throw (Tango::DevFailed); - - - //--------------------------------------------- - // Message::ctor - //--------------------------------------------- - explicit Message (CSPI_EVENT * evt, - size_t msg_priority = DEFAULT_MSG_PRIORITY, - bool waitable = false); - - //--------------------------------------------- - // Message::ctor - //--------------------------------------------- - explicit Message (size_t msg_type, - size_t msg_priority = DEFAULT_MSG_PRIORITY, - bool waitable = false); - - //--------------------------------------------- - // Message::dtor - //--------------------------------------------- - virtual ~Message (); - - //--------------------------------------------- - // Message::to_string - //--------------------------------------------- - const char * to_string (void) const; - - //--------------------------------------------- - // Message::is_ctrl_message - //--------------------------------------------- - bool is_ctrl_message (void); - - //--------------------------------------------- - // Message::duplicate - //--------------------------------------------- - Message * duplicate (void); - - //--------------------------------------------- - // Message::release - //--------------------------------------------- - void release (void); - - //--------------------------------------------- - // Message::type - //--------------------------------------------- - size_t type (void) const; - - //--------------------------------------------- - // Message::type - //--------------------------------------------- - size_t priority (void) const; - - //--------------------------------------------- - // Message::user_data - //--------------------------------------------- - void * user_data (void) const; - - //--------------------------------------------- - // Message::cspi_data - //--------------------------------------------- - void user_data (void * user_data); - - //--------------------------------------------- - // Message::cspi_data - //--------------------------------------------- - int cspi_data (void) const; - - //--------------------------------------------- - // Message::cspi_data - //--------------------------------------------- - void cspi_data (int _cspi_data); - - //--------------------------------------------- - // Message::attach_data - gets ownership - //--------------------------------------------- - template <typename T> void attach_data (T * _data, bool _ownership = true) - throw (Tango::DevFailed) - { - Container * md = new GenericContainer<T>(_data, _ownership); - if (md == 0) - { - Tango::Except::throw_exception (_CPTC("OUT_OF_MEMORY"), - _CPTC("MessageData allocation failed"), - _CPTC("Message::attach_data")); - } - this->msg_data_ = md; - } - - //--------------------------------------------- - // Message::attach_data - makes a copy - //--------------------------------------------- - template <typename T> void attach_data (const T & _data) - throw (Tango::DevFailed) - { - Container * md = new GenericContainer<T>(_data); - if (md == 0) - { - Tango::Except::throw_exception (_CPTC("OUT_OF_MEMORY"), - _CPTC("MessageData allocation failed"), - _CPTC("Message::attach_data")); - } - this->msg_data_ = md; - } - - //--------------------------------------------- - // Message::get_data - //--------------------------------------------- - template <typename T> T& get_data () const - throw (Tango::DevFailed) - { - try - { - GenericContainer<T> * c = dynamic_cast<GenericContainer<T>*>(this->msg_data_); - if (c == 0) - { - Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"), - _CPTC("could not extract data from message [unexpected content]"), - _CPTC("Message::msg_data")); - } - return c->content(); - } - catch(const std::bad_cast&) - { - Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"), - _CPTC("could not extract data from message [unexpected content]"), - _CPTC("Message::msg_data")); - } - } - - //--------------------------------------------- - // Message::detach_data - //--------------------------------------------- - template <typename T> void detach_data (T*& _data) const - throw (Tango::DevFailed) - { - try - { - GenericContainer<T> * c = dynamic_cast<GenericContainer<T>*>(this->msg_data_); - if (c == 0) - { - Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"), - _CPTC("could not extract data from message [unexpected content]"), - _CPTC("Message::msg_data")); - } - _data = c->content(true); - } - catch(const std::bad_cast&) - { - Tango::Except::throw_exception (_CPTC("RUNTIME_ERROR"), - _CPTC("could not extract data from message [unexpected content]"), - _CPTC("Message::msg_data")); - } - } - - //--------------------------------------------- - // Message::make_waitable - //-------------------------------------------- - void make_waitable (void) - throw (Tango::DevFailed); - - //--------------------------------------------- - // Message::waitable - //-------------------------------------------- - bool waitable (void) const; - - //--------------------------------------------- - // Message::wait_processed - //--------------------------------------------- - bool wait_processed (unsigned long tmo_ms); - - //--------------------------------------------- - // Message::processed - //--------------------------------------------- - void processed (void); - - //--------------------------------------------- - // Message::has_error - //--------------------------------------------- - bool has_error (void) const; - - //--------------------------------------------- - // Message::set_error - //--------------------------------------------- - void set_error (const Tango::DevFailed & e); - - //--------------------------------------------- - // Message::get_error - //--------------------------------------------- - const Tango::DevFailed & get_error (void) const; - -private: - //- the notification type - int type_; - - //- the msg priority - size_t priority_; - - //- the associated user data (common to all messages) - void * user_data_; - - //- the msg data (specific to a given message) - Container * msg_data_; - - //- the cspi data (from cspi evt) - int cspi_data_; - - //- condition variable (for waitable msgs) - Condition * cond_; - - //- true if a thread is "waiting" for the message to be handled - bool has_waiter_; - - //- true if an error occured during message handling - bool has_error_; - - //- true if msg has been processed - bool processed_; - - //- TANGO exception local storage - Tango::DevFailed exception_; - - // = Disallow these operations. - //-------------------------------------------- - Message & operator= (const Message &); - Message (const Message &); -}; - -} // namespace bpm - -#if defined (__INLINE_IMPL__) -# include "threading/Message.i" -#endif - -#endif // _BPM_MSG_H_ diff --git a/src/threading/MessageQ.cpp b/src/threading/MessageQ.cpp deleted file mode 100644 index 38f0c837fb758c5cf77d9634dda44a8ebe31139d..0000000000000000000000000000000000000000 --- a/src/threading/MessageQ.cpp +++ /dev/null @@ -1,425 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -// ============================================================================ -// DEPENDENCIES -// ============================================================================ -#include "CommonHeader.h" -#include "threading/MessageQ.h" - -#if !defined (__INLINE_IMPL__) -# include "threading/MessageQ.i" -#endif // __INLINE_IMPL__ - -namespace bpm -{ - -// ============================================================================ -// MessageQ::MessageQ -// ============================================================================ -MessageQ::MessageQ (size_t _lo_wm, size_t _hi_wm, bool _throw_on_post_tmo) - : msg_q_ (0), - msg_producer_sync_ (lock_), - msg_consumer_sync_ (lock_), - state_(MessageQ::OPEN), - enable_timeout_msg_ (false), - enable_periodic_msg_ (false), - lo_wm_ (_lo_wm), - hi_wm_ (_hi_wm), - saturated_ (false), - throw_on_post_msg_timeout_ (_throw_on_post_tmo), - last_returned_msg_periodic_ (true) -{ - this->last_periodic_msg_ts_.tv_sec = 0; - this->last_periodic_msg_ts_.tv_usec = 0; -} - -// ============================================================================ -// MessageQ::~MessageQ -// ============================================================================ -MessageQ::~MessageQ (void) -{ - bpm::AutoMutex<bpm::Mutex> (this->lock_); - - this->state_ = MessageQ::CLOSED; - - this->clear_i(); -} - -// ============================================================================ -// MessageQ::clear_i -// ============================================================================ -size_t MessageQ::clear_i (void) -{ - size_t num_msg_in_q = this->msg_q_.size(); - - while (! this->msg_q_.empty()) - { - Message * m = this->msg_q_.front (); - if (m) m->release(); - this->msg_q_.pop_front(); - } - - return num_msg_in_q; -} - -// ============================================================================ -// MessageQ::close -// ============================================================================ -void MessageQ::close (void) -{ - bpm::AutoMutex<bpm::Mutex> (this->lock_); - - this->state_ = MessageQ::CLOSED; -} - -// ============================================================================ -// MessageQ::post -// ============================================================================ -void MessageQ::post (bpm::Message * msg, size_t _tmo_msecs) - throw (Tango::DevFailed) -{ - //- check input - if (! msg) return; - - //- caller can't post any TIMEOUT or PERIODIC msg - if (msg->type() == TASK_TIMEOUT || msg->type() == TASK_PERIODIC) - { - //- silently trash the message - msg->release(); - return; - } - - //- enter critical section (required for cond.var. to work properly) - bpm::AutoMutex<bpm::Mutex> guard(this->lock_); - - //- can only post a msg on an opened MsgQ - if (this->state_ != MessageQ::OPEN) - { - //- silently trash the message (should we throw an exception instead?) - msg->release(); - return; - } - - //- we force post of ctrl message even if the msQ is saturated - if (msg->is_ctrl_message()) - { - //- insert msg according to its priority - try - { - this->insert_i(msg); - } - catch (...) - { - //- insert_i released the message (no memory leak) - Tango::Except::throw_exception (_CPTC ("INTERNAL_ERROR"), - _CPTC ("could not post ctrl message [msgQ insertion error]"), - _CPTC ("MessageQ::post")); - } - //- wakeup msg consumers (tell them there is a message to handle) - //- this will work since we are under critical section - msg_consumer_sync_.signal(); - //- done (skip remaining code) - return; - } - - //- is the messageQ saturated? - if (! this->saturated_ && (this->msg_q_.size() == this->hi_wm_)) - { - //- mark msgQ as saturated - this->saturated_ = true; - } - - //- msg is not a ctrl message... - //- wait for the messageQ to have room for new messages - if (! this->wait_not_full_i(_tmo_msecs)) - { - //- can't post msg, destroy it in order to avoid memory leak - msg->release(); - //- throw exception if the messageQ is configured to do so - if (this->throw_on_post_msg_timeout_) - { - Tango::Except::throw_exception (_CPTC ("TIMEOUT_EXPIRED"), - _CPTC ("could not post message [timeout expired]"), - _CPTC ("MessageQ::post")); - } - //- return if we didn't throw an exception - return; - } - - DEBUG_ASSERT(this->msg_q_.size() <= this->hi_wm_); - - //- insert the message according to its priority - try - { - this->insert_i(msg); - } - catch (...) - { - //- insert_i released the message (no memory leak) - Tango::Except::throw_exception (_CPTC ("INTERNAL_ERROR"), - _CPTC ("could not post message [msgQ insertion error]"), - _CPTC ("MessageQ::post")); - } - - //- wakeup msg consumers (tell them there is a new message to handle) - //- this will work since we are still under critical section - //-------------------------------------------------- - //-TODO: avoid using this under sys signal callback! - //-------------------------------------------------- - msg_consumer_sync_.signal (); -} - -// ============================================================================ -// MessageQ::post -// ============================================================================ -void MessageQ::post (CSPI_EVENT * _evt, size_t _tmo_msecs) - throw (Tango::DevFailed) -{ - //- check input - if (! _evt) return; - - bpm::Message * msg = 0; - - try - { - msg = new bpm::Message (_evt); - if (msg == 0) - throw std::bad_alloc (); - } - catch (const std::bad_alloc &) - { - Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"), - _CPTC ("memory allocation failed"), - _CPTC ("MessageQ::post")); - } - catch (...) - { - Tango::Except::throw_exception (_CPTC ("OUT_OF_MEMORY"), - _CPTC ("memory allocation failed"), - _CPTC ("MessageQ::post")); - } - - this->post(msg, _tmo_msecs); -} - -// ============================================================================ -// MessageQ::next_message -// ============================================================================ -bpm::Message * MessageQ::next_message (size_t _tmo_msecs) -{ - //- enter critical section (required for cond.var. to work properly) - bpm::AutoMutex<bpm::Mutex> guard(this->lock_); - - //- the msg - bpm::Message * msg = 0; - - //- wait for the messageQ to contain at least one message - //- bpm::Timer t; - //- std:cout << "[this:" << (long)this << "]" << " - wait_not_empty_i waiting for msg [tmo is " << _tmo_msecs << "]" << std::endl; - if (! this->wait_not_empty_i(_tmo_msecs)) - { - //- std::cout << "[this:" << (long)this << "]" << " - wait_not_empty_i returned false after " << t.elapsed_msec() << "ms [tmo was: " << _tmo_msecs << "]" << std::endl; - //- <wait_not_empty_i> returned <false> : means no msg in msg queue after <_tmo_msecs> - //- it may be time to return a periodic message - if (this->enable_periodic_msg_ && this->periodic_tmo_expired(_tmo_msecs)) - { - this->last_returned_msg_periodic_ = true; - GET_TIME(this->last_periodic_msg_ts_); - //- std::cout << "MessageQ::next_message::returning TASK_PERIODIC" << std::endl; - return new Message(TASK_PERIODIC); - } - //- else return a timeout msg - if (this->enable_timeout_msg_) - { - this->last_returned_msg_periodic_ = false; - //- std::cout << "MessageQ::next_message::returning TASK_TIMEOUT" << std::endl; - return new Message(TASK_TIMEOUT); - } - //- no msg - //- std::cout << "MessageQ::next_message::returning NULL msg" << std::endl; - this->last_returned_msg_periodic_ = false; - return 0; - } - - //- std::cout << "[this:" << (long)this << "]" << " - wait_not_empty_i returned true after " << t.elapsed_msec() << "ms [tmo was: " << _tmo_msecs << "]" << std::endl; - - //- ok, there should be at least one message in the messageQ - DEBUG_ASSERT(this->msg_q_.empty() == false); - - //- we are still under critical section since the "Condition::timed_wait" - //- located in "wait_not_empty_i" garantee that the associated mutex (i.e. - //- this->lock_ in the present case) is acquired when the function returns - - //- get msg from Q - msg = this->msg_q_.front(); - - //- parano. debugging - DEBUG_ASSERT(msg != 0); - - //- if the msg is a ctrl msg... - if (msg->is_ctrl_message()) - { - //... then extract it from the Q and return it - this->msg_q_.pop_front(); - //- if we reach the low water mark, then wakeup msg producer(s) - if (this->saturated_ && this->msg_q_.size() <= this->lo_wm_) - { - //- no longer saturated - this->saturated_ = false; - //- this will work since we are still under critical section - this->msg_producer_sync_.broadcast(); - } - //- we are about to return a ctrl msg so... - this->last_returned_msg_periodic_ = false; - //- return ctrl message - //- std::cout << "MessageQ::next_message::returning a CTRL msg" << std::endl; - return msg; - } - - //- avoid PERIODIC msg starvation (see note above) - if ( - this->enable_periodic_msg_ - && - this->periodic_tmo_expired(_tmo_msecs) - && - this->last_returned_msg_periodic_ == false - ) - { - //- we didn't actually extract the <msg> from the Q. - //- we just "accessed it using "pop_front" so no need to reinject it into the Q - this->last_returned_msg_periodic_ = true; - GET_TIME(this->last_periodic_msg_ts_); - //- std::cout << "MessageQ::next_message::returning TASK_PERIODIC msg" << std::endl; - return new Message(TASK_PERIODIC); - } - - //- we are about to return a msg from the Q so... - this->last_returned_msg_periodic_ = false; - - //- then extract it from the Q and return it - this->msg_q_.pop_front(); - - //- if we reach the low water mark, then wakeup msg producer(s) - if (this->saturated_ && this->msg_q_.size() <= this->lo_wm_) - { - //- no longer saturated - this->saturated_ = false; - //- this will work since we are still under critical section - this->msg_producer_sync_.broadcast(); - } - - //- std::cout << "MessageQ::next_message::returning USER msg" << std::endl; - - return msg; -} - -// ============================================================================ -// MessageQ::wait_not_empty_i -// ============================================================================ -bool MessageQ::wait_not_empty_i (size_t _tmo_msecs) -{ - //- <this->lock_> MUST be locked by the calling thread - //---------------------------------------------------- - - //- while the messageQ is empty... - while (this->msg_q_.empty()) - { - //- wait for a msg or tmo expiration - if (! this->msg_consumer_sync_.timed_wait(_tmo_msecs)) - return false; - } - - //- at least one message available in the MsgQ - return true; -} - -// ============================================================================ -// MessageQ::wait_not_full_i -// ============================================================================ -bool MessageQ::wait_not_full_i (size_t _tmo_msecs) -{ - //- <this->lock_> MUST be locked by the calling thread - //---------------------------------------------------- - - //- while the messageQ is full... - while (this->saturated_) - { - //- wait for some msgs to be consumed or tmo expiration - if (! this->msg_producer_sync_.timed_wait(_tmo_msecs)) - return false; - } - - //- at least one message available in the MsgQ - return true; -} - -// ============================================================================ -// Binary predicate -// ============================================================================ -static bool insert_msg_criterion (Message * const m1, Message * const m2) -{ - return m2->priority() < m1->priority(); -} - -// ============================================================================ -// MessageQ::insert_i -// ============================================================================ -void MessageQ::insert_i (Message * _msg) - throw (Tango::DevFailed) -{ - try - { - if (this->msg_q_.empty()) - { - //- optimization: no need to take count of the msg priority - this->msg_q_.push_front (_msg); - } - else - { - //- insert msg according to its priority - MessageQImpl::iterator pos = std::upper_bound(this->msg_q_.begin(), - this->msg_q_.end(), - _msg, - insert_msg_criterion); - this->msg_q_.insert(pos, _msg); - } - } - catch (...) - { - _msg->processed(); - _msg->release(); - Tango::Except::throw_exception (_CPTC ("INTERNAL_ERROR"), - _CPTC ("could insert message into the message queue"), - _CPTC ("MessageQ::insert_i")); - - } -} - -} // namespace bpm diff --git a/src/threading/MessageQ.h b/src/threading/MessageQ.h deleted file mode 100644 index ee8af1d8f7aab0b6bd4fa49d2267158a0834823f..0000000000000000000000000000000000000000 --- a/src/threading/MessageQ.h +++ /dev/null @@ -1,200 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -#ifndef _BPM_MSGQ_H_ -#define _BPM_MSGQ_H_ - -// ============================================================================ -// DEPENDENCIES -// ============================================================================ -#include <list> -#include "CommonHeader.h" -#include "threading/Message.h" - -// ============================================================================ -// CONSTs -// ============================================================================ -#define kDEFAULT_THD_TMO_MSECS 1000 -#if defined(kDEFAULT_MSG_TMO_MSECS) -# undef kDEFAULT_MSG_TMO_MSECS -#endif -#define kDEFAULT_MSG_TMO_MSECS 2500 -//----------------------------------------------------------------------------- -#define kDEFAULT_POST_MSG_TMO 1000 -#define kDEFAULT_LO_WATER_MARK 256 -#define kDEFAULT_HI_WATER_MARK 512 -#define kMIN_LO_WATER_MARK kDEFAULT_LO_WATER_MARK -#define kMIN_WATER_MARKS_DIFF kDEFAULT_LO_WATER_MARK -//----------------------------------------------------------------------------- - -namespace bpm -{ - -// ============================================================================ -// class: MessageQ -// ============================================================================ -class MessageQ -{ - friend class Task; - - typedef std::list<bpm::Message *> MessageQImpl; - -public: - - //- MessageQ has a state - typedef enum - { - OPEN, - CLOSED - } State; - - //- post a bpm::Message into the msgQ - void post (bpm::Message * msg, size_t tmo_msecs = kDEFAULT_POST_MSG_TMO) - throw (Tango::DevFailed); - - //- post a cspi event into the msgQ - void post (CSPI_EVENT * evt, size_t tmo_msecs = kDEFAULT_POST_MSG_TMO) - throw (Tango::DevFailed); - - //- extract next message from the msgQ - bpm::Message * next_message (size_t tmo_msecs); - - //- low water mark mutator - void lo_wm (size_t _lo_wm); - - //- low water mark accessor - size_t lo_wm () const; - - //- high water mark mutator - void hi_wm (size_t _hi_wm); - - //- high water mark accessor - size_t hi_wm () const; - - //- should the msgQ throw an exception on post msg tmo expiration? - void throw_on_post_msg_timeout (bool _strategy); - - //- clear msgQ content - void clear(); - - //- close the msqQ - void close (void); - - //- enable/disable timeout msg - void enable_timeout_msg (bool b); - bool timeout_msg_enabled () const; - - //- enable/disable handling flag - void enable_periodic_msg (bool b); - bool periodic_msg_enabled () const; - -private: - //- private ctor - MessageQ (size_t lo_wm = kDEFAULT_LO_WATER_MARK, - size_t hi_wm = kDEFAULT_HI_WATER_MARK, - bool throw_on_post_tmo = false); - - //- private ctor - virtual ~MessageQ (); - - //- check the periodic msg timeout - bool periodic_tmo_expired (double tmo_msecs) const; - - //- clears msgQ content (returns num of trashed messages) - size_t clear_i(); - - //- waits for the msQ to contain at least one msg - //- returns false if tmo expired, true otherwise. - bool wait_not_empty_i (size_t tmo_msecs); - - //- waits for the msQ to have room for new messages - //- returns false if tmo expired, true otherwise. - bool wait_not_full_i (size_t tmo_msecs); - - //- insert a msg according to its priority - void insert_i (Message * msg) - throw (Tango::DevFailed); - - //- use a std::deque to implement msgQ - MessageQImpl msg_q_; - - //- sync. object in order to make the msgQ thread safe - bpm::Mutex lock_; - - //- Producer(s) synch object - bpm::Condition msg_producer_sync_; - - //- Consumer synch object - bpm::Condition msg_consumer_sync_; - - //- state - MessageQ::State state_; - - //- timeout msg handling flag - bool enable_timeout_msg_; - - //- periodic msg handling flag - bool enable_periodic_msg_; - - //- last returned PERIODIC msg timestamp - TIME_VAL last_periodic_msg_ts_; - - //- low water marks - size_t lo_wm_; - - //- high water marks - size_t hi_wm_; - - //- msqQ saturation flag - bool saturated_; - - //- expection activation flag - bool throw_on_post_msg_timeout_; - - //- flag indicating whether or not the last returned msg was a periodoc msg - //- we use this flag in order to avoid PERIODIC event flooding in case - //- the PERIODIC event frequency is really high - which could prevent other - //- messages from being handled. reciprocally, a very high msg posting freq. - //- could prevent the PERIODIC msg from being handled. the following tries - //- to ensure that any msg is "finally" handled. - bool last_returned_msg_periodic_; - - // = Disallow these operations. - //-------------------------------------------- - MessageQ & operator= (const MessageQ &); - MessageQ (const MessageQ &); -}; - -} // namespace bpm - -#if defined (__INLINE_IMPL__) -# include "threading/MessageQ.i" -#endif // __INLINE_IMPL__ - -#endif // _BPM_MSGQ_H_ diff --git a/src/threading/Mutex.h b/src/threading/Mutex.h deleted file mode 100644 index b1fd465d4e30697e324d930a67f92d183f4225d0..0000000000000000000000000000000000000000 --- a/src/threading/Mutex.h +++ /dev/null @@ -1,237 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -#ifndef _BPM_MUTEX_H_ -#define _BPM_MUTEX_H_ - -// ============================================================================ -// DEPENDENCIES -// ============================================================================ -#include "threading/Utilities.h" -#include "threading/Implementation.h" - -// ============================================================================ -// Implementation-specific header file. -// ============================================================================ -#if ! defined(__MUTEX_IMPLEMENTATION) -# error "implementation header file incomplete [no mutex implementation]" -#endif - -namespace bpm { - -// ============================================================================ -//! <BPM_MUTEX>::try_lock may return one of the following MutexState -// ============================================================================ -typedef enum -{ - MUTEX_LOCKED, - MUTEX_BUSY, -} MutexState; - -// ============================================================================ -//! The BPM NullMutex class -// ============================================================================ -class NullMutex -{ - //! This is the yat NullMutex class. - //! - //! Provides a "do nothing" Mutex impl. May be used as template argument - //! in order to control the template instanciation and avoiding locking - //! overhead where thread safety is not required. - //! - //! template <typename LOCK> class OptionalThreadSafetyImpl - //! { - //! public: - //! inline void do_something (void) - //! { - //! yat::AutoMutex<LOCK>(this->m_mutex); - //! ... - //! } - //! private: - // LOCK m_mutex; - //! } - //! - //! OptionalThreadSafetyImpl<yat::Mutex> will be thread safe while... - //! OptionalThreadSafetyImpl<yat::NullMutex> will not be! - //! - //! This class is not supposed to be derived. - -public: - //! Constructor. - NullMutex (void); - - //! Destructor. - ~NullMutex (void); - - //! Locks (i.e. acquires) the mutex. - void lock (void); - - //! Locks (i.e. acquires) the mutex. - void acquire (void); - - //! Locks (i.e. acquires) the mutex. Always returns MUTEX_LOCKED. - MutexState try_lock (void); - - //! Locks (i.e. acquires) the mutex. Always returns MUTEX_LOCKED. - MutexState try_acquire (void); - - //! Unlocks (i.e. releases) the mutex. - void unlock (void); - - //! Unlocks (i.e. releases) the mutex. - void release (void); - -private: - //! Not implemented private member - NullMutex (const NullMutex&); - //! Not implemented private member - NullMutex & operator= (const NullMutex&); -}; - -// ============================================================================ -//! The BPM Mutex class -// ============================================================================ -class Mutex -{ - //! This is the yat Mutex implementation. - //! - //! This class is not supposed to be derived (no virtual destructor). - -public: - //! Constructor. - Mutex (void); - - //! Destructor. - ~Mutex (void); - - //! Locks (i.e. acquires) the mutex. - void lock (void); - - //! Locks (i.e. acquires) the mutex. - void acquire (void); - - //! Locks (i.e. acquires) the mutex. - //! Returns MUTEX_LOCKED in case the mutex was successfully locked. - //! Returns MUTEX_BUSY if it is already owned by another thread. - MutexState try_lock (void); - - //! Locks (i.e. acquires) the mutex. - //! Returns MUTEX_LOCKED in case the mutex was successfully locked. - //! Returns MUTEX_BUSY if it is already owned by another thread. - MutexState try_acquire (void); - - //! Unlocks (i.e. releases) the mutex. - void unlock (void); - - //! Unlocks (i.e. releases) the mutex. - void release (void); - -private: - //! Not implemented private member - Mutex (const Mutex&); - //! Not implemented private member - Mutex & operator= (const Mutex&); - - //- platform specific implementation - __MUTEX_IMPLEMENTATION; -}; - -// ============================================================================ -//! The BPM "auto mutex" class -// ============================================================================ -template <typename LOCK_TYPE = bpm::Mutex> class AutoMutex -{ - //! An "auto mutex" providing an auto lock/unlock mechanism. - //! - //! The AutoMutex is ideal in context where some exceptions may be thrown. - //! Whatever is the exit path of your code, the <AutoMutex> will garantee - //! that the associated <Mutex> is properly unlock. - //! - //! This class is template since it may be used in contexts in which the - //! thread safety is optionnal (see yat::NullMutex for an example). - //! - //! AutoMutex provides an efficient and safe alternative to: - //! - //! { //- enter critical section - //! my_mutex.lock(); - //! ...your critical section code goes here (may throw an exception)... - //! my_mutex.unlock(); - //! } //- leave critical section - //! - //! In such a context, you can use a instance AutoMutex as follows: - //! - //! { //- enter critical section - //! yat::AutoMutex<> guard(my_mutex); - //! ...your critical section code goes here (may throw an exception)... - //! } //- leave critical section - //! - //! This has the advantage that my_mutex.unlock() will be called automatically - //! even if an exception is thrown. Since the AutoMutex is created on the stack - //! its destructor will be called whatever is the exit path of critical section. - //! - //! Note that AutoMutex can be used with any "LOCK_TYPE" which interface contains - //! both a lock(void) and a unlock(void) method. The yat::SharedObject class of - //! such a compatible "LOCK_TYPE". - //! -public: - //! Constructor (locks the associated Mutex) - AutoMutex (LOCK_TYPE & _lock) - : m_lock (_lock) - { - m_lock.lock(); - } - - //! Destructor (unlocks the associated Mutex) - ~AutoMutex (void) - { - m_lock.unlock(); - } - -private: - //! The associated Mutex - LOCK_TYPE & m_lock; - - //! Not implemented private member - AutoMutex (const AutoMutex&); - //! Not implemented private member - AutoMutex & operator= (const AutoMutex&); -}; - -// ============================================================================ -//! MutexLock: an AutoMutex specialisation (for backforward compatibility) -// ============================================================================ -typedef AutoMutex<Mutex> MutexLock; - -} // namespace bpm - -#if defined (__INLINE_IMPL__) -# include "threading/impl/PosixMutexImpl.i" -#endif - -#endif //- _BPM_MUTEX_H_ diff --git a/src/threading/Semaphore.h b/src/threading/Semaphore.h deleted file mode 100644 index 32975eed7aca229d90e52922a33183850e103918..0000000000000000000000000000000000000000 --- a/src/threading/Semaphore.h +++ /dev/null @@ -1,142 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -#ifndef _BPM_SEMAPHORE_H_ -#define _BPM_SEMAPHORE_H_ - -// ============================================================================ -// DEPENDENCIES -// ============================================================================ -#include "threading/Implementation.h" -#include "threading/Mutex.h" -#include "threading/Condition.h" - -// ============================================================================ -// Implementation-specific header file. -// ============================================================================ -#if ! defined(__SEMAPHORE_IMPLEMENTATION) -# error "implementation header file incomplete [no semaphore implementation]" -#endif - -namespace bpm { - -// ============================================================================ -//! <BPM_SEMAPHORE>::try_wait may return one of the following SemaphoreState -// ============================================================================ -typedef enum -{ - //! semaphore is currently "decrementable" - SEMAPHORE_DEC, - //! no resource available (semaphore value is 0) - SEMAPHORE_NO_RSC, -} SemaphoreState; - -// ============================================================================ -//! The BPM Semaphore class -// ============================================================================ -class Semaphore -{ - //! This is the BPM Semaphore class. - //! - //! This class is not supposed to be derived. - -public: - //! Constructor (may throw an Exception) - Semaphore (unsigned int initial = 1); - - //! Destructor. - ~Semaphore (void); - - //! If semaphore value is > 0 then decrement it and carry on. - //! If it's already 0 then block untill the semaphore is either "signaled" - //! or "broascasted" (see post, signal and broadcast members below). - void wait (void); - - //! If semaphore value is > 0 then decrements it and returns true. Returns - //! "false" in case the specified timeout expired before the semaphore - //! has been "signaled" or "broascasted" by another thread. - bool timed_wait (unsigned long tmo_msecs); - - //! If the current semaphore value is > 0, then crements it and returns - //! SEMAPHORE_DEC. In case the semaphore has reached its maximum value, - //! this method does not block and "immediately" returns SEMAPHORE_NO_RSC. - SemaphoreState try_wait (void); - - //! If any threads are blocked in wait(), wake one of them up. - //! Otherwise increments the value of the semaphore. - void post (void); - -private: - //! Not implemented private member - Semaphore (const Semaphore&); - //! Not implemented private member - Semaphore & operator= (const Semaphore&); - - //- platform specific implementation - __SEMAPHORE_IMPLEMENTATION; -}; - -// ============================================================================ -//! The BPM "auto semaphore" class -// ============================================================================ -class AutoSemaphore -{ - //! An "auto semaphore" providing an auto wait/post mechanism. - -public: - //! Constructor (wait on the associated Semaphore) - AutoSemaphore (Semaphore & _sem) - : m_sem (_sem) - { - m_sem.wait(); - } - - //! Destructor (post the associated Semaphore) - ~AutoSemaphore (void) - { - m_sem.post(); - } - -private: - //! The associated Mutex - Semaphore & m_sem; - - //! Not implemented private member - AutoSemaphore (const AutoSemaphore&); - //! Not implemented private member - AutoSemaphore & operator= (const AutoSemaphore&); -}; - -} // namespace bpm - -#if defined (__INLINE_IMPL__) -# include "threading/impl/PosixSemaphoreImpl.i" -#endif - -#endif //- _BPM_SEMAPHORE_H_ diff --git a/src/threading/SharedObject.cpp b/src/threading/SharedObject.cpp deleted file mode 100644 index 5ebee01cc55c13c9a460e573e3322667f3dcd645..0000000000000000000000000000000000000000 --- a/src/threading/SharedObject.cpp +++ /dev/null @@ -1,101 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -// ============================================================================ -// DEPENDENCIES -// ============================================================================ -#include "threading/SharedObject.h" - -#if !defined (__INLINE_IMPL__) -# include "threading/SharedObject.i" -#endif - -namespace bpm -{ -// ============================================================================ -// SharedObject::SharedObject -// ============================================================================ -SharedObject::SharedObject (void) : reference_count_ (1) -{ - //- noop -} - -// ============================================================================ -// SharedObject::~SharedObject -// ============================================================================ -SharedObject::~SharedObject (void) -{ - //- check reference_count_ value - DEBUG_ASSERT(this->reference_count_ == 0); -} - -// ============================================================================ -// SharedObject::duplicate -// ============================================================================ -SharedObject *SharedObject::duplicate (void) -{ - AutoMutex<Mutex> guard (this->lock_); - - this->reference_count_++; - - return this; -} - -// ============================================================================ -// SharedObject::release -// ============================================================================ -void SharedObject::release (void) -{ - //- the try/catch block is a trick for embedded version... - try - { - if (this->release_i () == 0) - delete this; - } - catch (...) - { - //- ignore exception - } -} - -// ============================================================================ -// SharedObject::release_i -// ============================================================================ -SharedObject *SharedObject::release_i (void) -{ - AutoMutex<Mutex> guard (this->lock_); - - DEBUG_ASSERT(this->reference_count_ > 0); - - this->reference_count_--; - - return (this->reference_count_ == 0) ? 0 : this; -} - -} //- namespace bpm diff --git a/src/threading/SharedObject.h b/src/threading/SharedObject.h deleted file mode 100644 index 013366a403611e2aa754c405bb3976ba2a098fbf..0000000000000000000000000000000000000000 --- a/src/threading/SharedObject.h +++ /dev/null @@ -1,100 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -#ifndef _SHARED_OBJECT_H_ -#define _SHARED_OBJECT_H_ - -// ============================================================================ -// DEPENDENCIES -// ============================================================================ -#include "CommonHeader.h" -#include "threading/Mutex.h" - -namespace bpm -{ - -// ============================================================================ -//! A reference counted object abstraction. -// ============================================================================ -//! -//! Base class for any reference counted object (i.e. shared) object. -//! -// ============================================================================ -class SharedObject -{ -public: - - SharedObject (void); - // Constructor. - - virtual ~SharedObject (void); - // Destructor. - - SharedObject *duplicate (void); - // Return a "shallow" copy. Increment the reference count by 1 - // to avoid deep copies. - - void release (void); - // Decrease the shared reference count by 1. If the reference count - // equals 0, then delete <this> and return 0. Behavior is undefined - // if reference count < 0. - - int reference_count (void) const; - // Returns the current reference count. - - void lock (void); - // Gets exclusive access to the data. - - void unlock (void); - // Release exclusive access to the data. - -protected: - // a mutex to protect the data against race conditions - bpm::Mutex lock_; - -private: - // internal release implementation - SharedObject * release_i (void); - - //- reference count for (used to avoid deep copies) - int reference_count_; - - // = Disallow these operations. - //-------------------------------------------- - SharedObject & operator= (const SharedObject &); - SharedObject (const SharedObject &); -}; - -} // namespace bpm - -#if defined (__INLINE_IMPL__) -# include "threading/SharedObject.i" -#endif - -#endif // _SHARED_OBJECT_H_ diff --git a/src/threading/Task.cpp b/src/threading/Task.cpp deleted file mode 100644 index f4d81fcc59b272e8b0bb24ecf177cbe0c2010545..0000000000000000000000000000000000000000 --- a/src/threading/Task.cpp +++ /dev/null @@ -1,449 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -// ============================================================================ -// DEPENDENCIES -// ============================================================================ -#include "CommonHeader.h" -#include "threading/Task.h" - -#if !defined (__INLINE_IMPL__) -# include "threading/Task.i" -#endif - -namespace bpm -{ - -// ====================================================================== -// Task::Config::Config -// ====================================================================== - Task::Config::Config () - : enable_timeout_msg (false), - timeout_msg_period_ms (0), - enable_periodic_msg (false), - periodic_msg_period_ms (0), - lock_msg_handling (false), - lo_wm (kDEFAULT_LO_WATER_MARK), - hi_wm (kDEFAULT_HI_WATER_MARK), - throw_on_post_tmo (false), - msg_handler (0), - user_data (0), - host_device (0) -{ - /* noop ctor */ -} - -// ====================================================================== -// Task::Config::Config -// ====================================================================== - Task::Config::Config (Tango::DeviceImpl * _hd, - MessageHandler _msg_handler, - Thread::IOArg _user_data, - bool _enable_periodic_msg, - size_t _periodic_msg_period_ms, - bool _enable_timeout_msg, - size_t _timeout_msg_period_ms, - bool _lock_msg_handling, - size_t _lo_wm, - size_t _hi_wm, - bool _throw_on_post_tmo) - : enable_timeout_msg (_enable_timeout_msg), - timeout_msg_period_ms (_timeout_msg_period_ms), - enable_periodic_msg (_enable_periodic_msg), - periodic_msg_period_ms (_periodic_msg_period_ms), - lock_msg_handling (_lock_msg_handling), - lo_wm (_lo_wm), - hi_wm (_hi_wm), - throw_on_post_tmo (_throw_on_post_tmo), - msg_handler (_msg_handler), - user_data (_user_data), - host_device (_hd) -{ - /* noop ctor */ -} - -// ====================================================================== -// Task::Task -// ====================================================================== -Task::Task (const Task::Config& _cfg) - : Thread (_cfg.host_device), - msg_q_ (_cfg.lo_wm, _cfg.hi_wm, _cfg.throw_on_post_tmo), - timeout_msg_period_ms_ (_cfg.timeout_msg_period_ms), - periodic_msg_period_ms_ (_cfg.periodic_msg_period_ms), - user_data_ (_cfg.user_data), - lock_msg_handling_ (_cfg.lock_msg_handling), - henv_ (0), - hcon_ (0), - msg_handler_ (_cfg.msg_handler), - connected_ (false) -{ - this->msg_q_.enable_timeout_msg(_cfg.enable_timeout_msg); - this->msg_q_.enable_periodic_msg(_cfg.periodic_msg_period_ms); -} - -// ====================================================================== -// Task::~Task -// ====================================================================== -Task::~Task (void) -{ - //- noop -} - -// ============================================================================ -// Task::go -// ============================================================================ -void Task::go (size_t _tmo_ms) - throw (Tango::DevFailed) -{ - this->start_undetached(); - - Message * msg = 0; - try - { - msg = bpm::Message::allocate(TASK_INIT, INIT_MSG_PRIORITY, true); - } - catch (Tango::DevFailed & ex) - { - Tango::Except::throw_exception (_CPTC("OUT_OF_MEMORY"), - _CPTC("Message allocation failed"), - _CPTC("Task::go")); - } - - this->wait_msg_handled (msg, _tmo_ms); -} - -// ============================================================================ -// Task::go -// ============================================================================ -void Task::go (Message * _msg, size_t _tmo_ms) - throw (Tango::DevFailed) -{ - this->start_undetached(); - - if ( - (_msg == 0) - || - (_msg->type() != TASK_INIT) - || - (_msg->waitable() == false) - ) - Tango::Except::throw_exception (_CPTC("PROGRAMMING_ERROR"), - _CPTC("invalid INIT message [null, wrong type or not waitable]"), - _CPTC("Task::go")); - - this->wait_msg_handled (_msg, _tmo_ms); -} - -// ============================================================================ -// Task::run_undetached -// ============================================================================ -void * Task::run_undetached (void *) -{ - //- init flag - set to true when TASK_INIT received - bool received_init_msg = false; - - //- exit flag - set to true when TASK_EXIT received - bool received_exit_msg = false; - - size_t msg_type; - Message * msg = 0; - - //- actual tmo on msg waiting - size_t tmo = this->actual_timeout(); - - //- trick: avoid handling TIMEOUT messages before INIT is itself handled - //- may be the case for very short Task timeout - do - { - //- release any previously obtained msg - if (msg) msg->release(); - - //- get/wait next message from the msgQ - msg = this->msg_q_.next_message (tmo); - } - while (! msg || msg->type() != TASK_INIT); - - //- TASK_INIT received - received_init_msg = true; - - //- enter thread's main loop - while (! received_exit_msg) - { - //- actual tmo on msg waiting - tmo = this->actual_timeout(); - - //- get/wait next message from the msgQ - if (! msg) - { - do - { - //- get next message - msg = this->msg_q_.next_message (tmo); - //- do not handle TASK_INIT twice - if (msg && msg->type() == TASK_INIT && received_init_msg) - { - msg->release(); - msg = 0; - } - } - while (! msg); - } - - //- set msg user data - msg->user_data(this->user_data_); - - //- we may need msg type after msg release - msg_type = msg->type(); - - //- got a valid message from message Q - try - { - // std::cout << "Task::handling msg::" - // << std::hex - // << long(msg) - // << std::dec - // << "::" - // << msg->to_string() - // << std::endl; - //- call message handler - if (this->lock_msg_handling_) - { - //- enter critical section - MutexLock guard (this->m_lock); - (this->msg_handler_)(*msg); - } - else - { - this->msg_handler_(*msg); - } - } - catch (const Tango::DevFailed& e) - { - //- store exception into the message - msg->set_error(e); - } - catch (...) - { - Tango::DevErrorList errors; - errors.length(1); - errors[0].severity = Tango::ERR; - errors[0].reason = CORBA::string_dup("UNKNOWN_ERROR"); - errors[0].origin = CORBA::string_dup("unknown error caught while handling msg"); - errors[0].desc = CORBA::string_dup("Task::run_undetached"); - msg->set_error(Tango::DevFailed(errors)); - } - // std::cout << "Task::run_undetached::msg [" - // << std::hex - // << (void*)msg - // << std::dec - // << "] handled - notifying waiters" - // << std::endl; - //- mark message as "processed" (this will signal waiters if any) - msg->processed(); - //- release our msg ref - msg->release(); - //- abort requested? - if (msg_type == TASK_EXIT) - { - //- close the msgQ - this->msg_q_.close(); - //- mark TASK_EXIT as received (exit thread's main loop) - received_exit_msg = true; - } - //- reset msg in order to get next msg from msgQ - msg = 0; - } //- thread's while loop - - return 0; -} - -// ====================================================================== -// Task::exit -// ====================================================================== -void Task::exit (void) - throw (Tango::DevFailed) -{ - //- we may have to implicitly delete the thread - bool delete_self = false; - - //- enter critical section - this->m_lock.lock(); - - //- get underlying thread state - Thread::State ts = this->state_i(); - - //- if the thread is running, then ask it to exit - if (ts == bpm::Thread::STATE_RUNNING) - { - bpm::Message * msg = 0; - try - { - msg = new Message(bpm::TASK_EXIT, EXIT_MSG_PRIORITY, true); - } - catch (Tango::DevFailed &ex) - { - this->m_lock.unlock(); - Tango::Except::re_throw_exception (ex, - _CPTC("SOFTWARE_ERROR"), - _CPTC("Could not stop task [bpm::Message allocation failed]"), - _CPTC("Task::exit")); - } - catch (...) - { - this->m_lock.unlock(); - Tango::Except::throw_exception (_CPTC("UNKNOWN_ERROR"), - _CPTC("Could not stop task [bpm::Message allocation failed]"), - _CPTC("Task::exit")); - } - //- unlock the thread lock (avoid deadlock during message handling) - this->m_lock.unlock(); - try - { - //- ... then wait for TASK_EXIT msg to be handled - //- TODO: change kINFINITE_WAIT to a more flexible TIMEOUT - // std::cout << "Task::exit - waiting for the TASK_EXIT msg to be handled" << std::endl; - this->wait_msg_handled (msg, kINFINITE_WAIT); - } - catch (...) - { - //- ignore any error - } - //- wait for the thread to actually quit - try - { - Thread::IOArg dummy = 0; - // std::cout << "Task::exit - about to join with the underlying thread" << std::endl; - this->join (&dummy); - } - catch (...) - { - //- ignore any error - } - } - else if (ts == bpm::Thread::STATE_NEW) - { - //- delete the thread (instanciated but never been started) - // std::cout << "Task::exit - about to delete the thread [has never been started]" << std::endl; - delete_self = true; - //- leave critical section - this->m_lock.unlock(); - } - else - { - //- nothing to do... - // std::cout << "Task::exit - do nothing" << std::endl; - //- leave critical section - this->m_lock.unlock(); - } - - //- delete (if required) - if (delete_self) - { - // std::cout << "Task::exit - deleting <this> Task instance" << std::endl; - delete this; - } -} - -// ====================================================================== -// Task::wait_msg_handled -// ====================================================================== -void Task::wait_msg_handled (Message * _msg, size_t _tmo_ms) - throw (Tango::DevFailed) -{ - //- check input - if (! _msg || ! _msg->waitable()) - { - Tango::Except::throw_exception (_CPTC("INVALID_ARGUMENT"), - _CPTC("invalid message [either null or not waitable]"), - _CPTC("Task::wait_msg_handled")); - } - - try - { - //- post a shallow copy of the msg - this->msg_q_.post(_msg->duplicate()); - } - catch (...) - { - _msg->release(); - Tango::Except::throw_exception (_CPTC("INTERNAL_ERROR"), - _CPTC("message could not be posted"), - _CPTC("Task::wait_msg_handled")); - } - - // std::cout << "Task::wait_msg_handled::waiting for msg [" - // << std::hex - // << (void*)_msg - // << std::dec - // << "] to be handled" - // << std::endl; - - //- wait for the msg to be handled or tmo expiration - if (_msg->wait_processed(_tmo_ms)) - { - // std::cout << "Task::wait_msg_handled::msg [" - // << std::hex - // << (void*)_msg - // << std::dec - // << "] handled [gave error::" - // << (_msg->has_error() ? "yes" : "no") - // << "]" - // << std::endl; - Tango::DevFailed msg_exception; - bool msg_gave_error = _msg->has_error(); - //- to store error localy before releasing msg - if (msg_gave_error) - msg_exception = _msg->get_error(); - //- release msg - _msg->release(); - //- throw an exception if msg gave error - if (msg_gave_error) - throw msg_exception; - //- msg did not gave error, just return - return; - } - - //- too bad, timeout expired... - // std::cout << "Task::wait_msg_handled::timeout expired while waiting for msg [" - // << std::hex - // << (void*)_msg - // << std::dec - // << "] to be handled" - // << std::endl; - - //- release msg - _msg->release(); - - //- throw timeout exception - Tango::Except::throw_exception (_CPTC ("TIMEOUT_EXPIRED"), - _CPTC ("timeout expired while waiting for message to be handled"), - _CPTC ("Task::wait_msg_handled")); -} - -} // namespace diff --git a/src/threading/Task.h b/src/threading/Task.h deleted file mode 100644 index 4eafde9992efbe59f13a235fb90574c38ce8c81e..0000000000000000000000000000000000000000 --- a/src/threading/Task.h +++ /dev/null @@ -1,205 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -#ifndef _BPM_TASK_H_ -#define _BPM_TASK_H_ - -// ============================================================================ -// DEPENDENCIES -// ============================================================================ -#include "threading/Thread.h" -#include "threading/MessageQ.h" - -// ============================================================================ -// CONSTs -// ============================================================================ -#define kDEFAULT_TASK_TMO_MSECS 5000 -#define kDEFAULT_THD_PERIODIC_TMO_MSECS 1000 -//----------------------------------------------------------------------------- - -namespace bpm -{ - -// ============================================================================ -// class: Task -// ============================================================================ -class Task : public bpm::Thread -{ - friend class BPM; - -public: - - //-define what a msg handler is - typedef void (*MessageHandler) (const bpm::Message&); - - //! yat::Task configuration class - class Config - { - public: - //- enable TIMEOUT messages - bool enable_timeout_msg; - //- timeout msg period in msec - size_t timeout_msg_period_ms; - //- enable PERIODIC messages - bool enable_periodic_msg; - //- periodic msg period in msec - size_t periodic_msg_period_ms; - //- should we process msg under critical section? - bool lock_msg_handling; - //- msgQ low water mark - size_t lo_wm; - //- msgQ high water mark - size_t hi_wm; - //- throw exception on post message timeout - bool throw_on_post_tmo; - //- msg handler - MessageHandler msg_handler; - //- user data (passed back in all msg) - Thread::IOArg user_data; - //- host TANGO device - Tango::DeviceImpl * host_device; - - //- default ctor - Config (); - - //- ctor - Config (Tango::DeviceImpl * hd, - MessageHandler msg_handler, - Thread::IOArg user_data = 0, - bool enable_periodic_msg = false, - size_t periodic_msg_period_ms = 0, - bool enable_timeout_msg = false, - size_t timeout_msg_period_ms = 0, - bool lock_msg_handling = false, - size_t lo_wm = kDEFAULT_LO_WATER_MARK, - size_t hi_wm = kDEFAULT_HI_WATER_MARK, - bool throw_on_post_tmo = true); - }; - - //- ctor - Task (const Config& cfg); - - //- dtor - virtual ~Task (void); - - //- starts the task - void go (size_t _tmo_ms = kDEFAULT_MSG_TMO_MSECS) - throw (Tango::DevFailed); - - //- starts the task - //- an exception is thrown otherwise in case the specified message: - //- * is not of type TASK_INIT - //- * is not "waitable" - void go (Message * msg, size_t _tmo_ms = kDEFAULT_MSG_TMO_MSECS) - throw (Tango::DevFailed); - - //! Abort the task (join with the underlying thread before returning). - //! Provides an implementation to the Thread::exit pure virtual method. - virtual void exit (void) - throw (Tango::DevFailed); - - //- posts a message to the task - void post (Message * msg, size_t tmo_msecs = kDEFAULT_POST_MSG_TMO) - throw (Tango::DevFailed); - - //- post a CSPI event to the task - void post (CSPI_EVENT * evt, size_t tmo_msecs = kDEFAULT_POST_MSG_TMO) - throw (Tango::DevFailed); - - //- wait for a msg to be handled - void wait_msg_handled (Message * msg, size_t tmo_ms = kDEFAULT_MSG_TMO_MSECS) - throw (Tango::DevFailed); - - //- timeout msg period mutator - void set_timeout_msg_period (size_t p_msecs); - - //- periodic msg period accessor - size_t get_timeout_msg_period (void) const; - - //- enable/disable timeout messages - void enable_timeout_msg (bool enable); - - //- returns timeout messages handling status - bool timeout_msg_enabled (void) const; - - //- periodic msg period mutator - void set_periodic_msg_period (size_t p_msecs); - - //- periodic msg period accessor - size_t get_periodic_msg_period (void) const; - - //- enable/disable periodic messages - void enable_periodic_msg (bool enable); - - //- returns period messages handling status - bool periodic_msg_enabled (void) const; - -protected: - //- run_undetached - virtual Thread::IOArg run_undetached (Thread::IOArg); - -private: - //- actual_timeout - size_t actual_timeout (void) const; - - //- the associated messageQ - MessageQ msg_q_; - - //- timeout msg period - size_t timeout_msg_period_ms_; - - //- periodic msg period - size_t periodic_msg_period_ms_; - - //- user data - Thread::IOArg user_data_; - - //- should we process msg under critical section? - bool lock_msg_handling_; - - //- the CSPI env. handle - CSPIHENV henv_; - - //- the CSPI con. handle - CSPIHCON hcon_; - - //- the message handler entry point - MessageHandler msg_handler_; - - //- connection flag: true if connected to the Libera, false ortherwise - bool connected_; -}; - -} // namespace - -#if defined (__INLINE_IMPL__) -# include <threading/Task.i> -#endif - -#endif // _BPM_TASK_H_ diff --git a/src/threading/Thread.h b/src/threading/Thread.h deleted file mode 100644 index 7d9287c627cec0ea62ca1daecac774d6104c12c9..0000000000000000000000000000000000000000 --- a/src/threading/Thread.h +++ /dev/null @@ -1,207 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -#ifndef _BPM_THREAD_H_ -#define _BPM_THREAD_H_ - -// ---------------------------------------------------------------------------- -// DEPENDENCIES -// ---------------------------------------------------------------------------- -#include "threading/Mutex.h" - -// ---------------------------------------------------------------------------- -// Implementation-specific header file. -// ---------------------------------------------------------------------------- -#if ! defined(__THREAD_IMPLEMENTATION) -# error "implementation header file incomplete [no thread implementation]" -#endif - -namespace bpm { - -// ---------------------------------------------------------------------------- -//! The bpm Thread abstract class -// ---------------------------------------------------------------------------- -class Thread : public Tango::LogAdapter -{ - //! This abstract class can't be used as this and must be derived. - //! Provides both "detached" and "undetached" (i.e. joinable) behaviour. - -public: - //! A dedicated type for thread entry point argument (user specified data). - typedef void * IOArg; - - //! The possible thread priorities (default is NORMAL). - //! Be aware that setting the thread priority to HIGH or RT may - //! prevent other threads from running (CPU starvation). - enum Priority - { - PRIORITY_LOW, - PRIORITY_NORMAL, - PRIORITY_HIGH, - PRIORITY_RT - }; - - //! The possible thread states - enum State - { - //! Thread object exists but thread hasn't started yet. - //! In this state, the thread UID (identifier) is undefined. - STATE_NEW, - //! Thread is running. - STATE_RUNNING, - //! Thread has terminated but storage has not been reclaimed (i.e. waiting to be joined). - STATE_TERMINATED - }; - - //! Returns the the thread unique indentifier. - //! In case the thread is not yet running (THREAD_STATE_NEW), self will returns - //! YAT_INVALID_THREAD_UID (since the thread UID is not defined in this state). - ThreadUID self (void) const; - - //! Set the priority of the thread. - //! In case the thread is running, the priority is immediately applied. - void priority (Priority p) - throw (Tango::DevFailed); - - //! Returns the current priority of the thread. - Thread::Priority priority (void); - - //! Returns the current state of the thread. - //! \remarks Locks the associated Mutex (\c m_lock) - Thread::State state (void); - - //! This pure virtual member _must_ cause the "run" (for detached threads) - //! or "run_undetached" (for undetached threads) to return. In other words, - //! exit _must_ make the thread quit its "infinite loop" and quit. Its - //! content in purely application dependent - that's why the actual - //! implementation is delegated to the derived class. - virtual void exit (void) = 0; - - //! Returns the associated mutex - Mutex & lock (void); - - //! Allows another thread to run. - static void yield (void); - - //! Causes the thread to sleep for the given time. - static void sleep (unsigned long msecs); - -protected: - //! This constructor is used in a derived class. The thread will - //! execute the run() or run_undetached() member functions depending on - //! whether start() or start_undetached() is called respectively. - Thread (Tango::DeviceImpl * hd, - IOArg a = 0, - Priority p = bpm::Thread::PRIORITY_NORMAL); - - //! Causes the thread to be detached. - //! In this case the thread executes the run member function. - void start (void) - throw (Tango::DevFailed); - - //! Causes the thread to be undetached. - //! In this case the thread executes the run_undetached member function. - void start_undetached (void) - throw (Tango::DevFailed); - - //! Join causes the calling thread to wait for another's completion, - //! putting the return value in the variable of type IOArg whose address - //! is given (unless passed a null pointer). Only undetached threads - //! may be joined. Storage for the thread will be reclaimed. May throw an - //! exception in case the thread is either "not running" or "terminated". - //! An exception will also be thrown in case the thread is "detached" or - //! in case the underlying OS "wait for the thread to terminate" call fails. - void join (Thread::IOArg *) - throw (Tango::DevFailed); - - //! The Thread destructor cannot be called by user (except via a derived class). - //! Use exit() instead. This also means a thread object must be allocated with - //! new - it cannot be statically or automatically allocated. The destructor of - //! a class that inherits from omni_thread shouldn't be public either (otherwise - //! the thread object can be destroyed while the underlying thread is still running). - virtual ~Thread (void); - - //! Default implementation of the run method (detached thread). - //! Should be overridden in a derived class. Called by start() - virtual void run (Thread::IOArg) - { - //- noop - DEBUG_ASSERT(true); - } - - //! Default implementation of the run_undetached method (undetached thread). - //! Should be overridden in a derived class. Called by start_undetached() - virtual IOArg run_undetached (Thread::IOArg) - { - DEBUG_ASSERT(true); - return 0; - } - - //! The following mutex is used to protect any members which can change - //! after construction (such as m_state, m_priority, ...) - bpm::Mutex m_lock; - - //! Returns the current state of the thread. - //! \remarks Does not lock the associated Mutex (\c m_lock) - Thread::State state_i (void) const; - -private: - //! The current TState of the thread. - State m_state; - - //! The current TPriority of the thread. - Priority m_priority; - - //! The thread input argument - Thread::IOArg m_iarg; - - //! The thread returned value - Thread::IOArg m_oarg; - - //! Detached/undetached flag - bool m_detached; - - //! The thread identifier - ThreadUID m_uid; - - //! Not implemented private members - Thread (const Thread&); - Thread & operator= (const Thread&); - - //- platform specific implementation - __THREAD_IMPLEMENTATION; -}; - -} // namespace bpm - -#if defined (__INLINE_IMPL__) -# include "threading/impl/PosixThreadImpl.i" -#endif - -#endif //- _BPM_THREAD_H_ diff --git a/src/threading/Utilities.h b/src/threading/Utilities.h deleted file mode 100644 index 8624e49694e2bb9f622b4518aeea7ebca72e3ac3..0000000000000000000000000000000000000000 --- a/src/threading/Utilities.h +++ /dev/null @@ -1,79 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - - -#ifndef _BPM_THREADING_UTILS_H_ -#define _BPM_THREADING_UTILS_H_ - -// ============================================================================ -// DEPENDENCIES -// ============================================================================ -#include "threading/Implementation.h" - -// ============================================================================ -// CONSTs -// ============================================================================ -#define BPM_INVALID_THREAD_UID 0xffffffff - -namespace bpm { - -// ============================================================================ -//! A dedicated type for thread identifier -// ============================================================================ -typedef unsigned long ThreadUID; - -// ============================================================================ -//! The BPM threading utilities -// ============================================================================ -class ThreadingUtilities -{ -public: - //! Returns the calling thread identifier. - static ThreadUID self (void); - - //! Causes the caller to sleep for the given time. - static void sleep (unsigned long secs, unsigned long nanosecs = 0); - - //! Calculates an absolute time in seconds and nanoseconds, suitable for - //! use in timed_waits, which is the current time plus the given relative - //! offset. - static void get_time (unsigned long & abs_sec, - unsigned long & abs_nsec, - unsigned long offset_sec = 0, - unsigned long offset_nsec = 0); - - //! Calculates an absolute time in seconds and nanoseconds, suitable for - //! use in timed_waits, which is the current time plus the given relative - //! offset. WORKS ONLY FOR <delay_msecs> < 1 SECS. - static void get_time (unsigned long delay_msecs, Timespec& abs_time); -}; - -} // namespace bpm - -#endif //- _BPM_THREADING_UTILS_H_ diff --git a/src/threading/impl/PosixConditionImpl.i b/src/threading/impl/PosixConditionImpl.i deleted file mode 100644 index ed7c3c0f9bd26b70f50e78d5536336839a2376c8..0000000000000000000000000000000000000000 --- a/src/threading/impl/PosixConditionImpl.i +++ /dev/null @@ -1,56 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -namespace bpm { - -// ---------------------------------------------------------------------------- -// Condition::wait -// ---------------------------------------------------------------------------- -INLINE_IMPL void Condition::wait (void) -{ - this->timed_wait(0); -} - -// ---------------------------------------------------------------------------- -// Condition::signal -// ---------------------------------------------------------------------------- -INLINE_IMPL void Condition::signal (void) -{ - ::pthread_cond_signal(&m_posix_cond); -} - -// ---------------------------------------------------------------------------- -// Condition::broadcast -// ---------------------------------------------------------------------------- -INLINE_IMPL void Condition::broadcast (void) -{ - ::pthread_cond_broadcast(&m_posix_cond); -} - -} // namespace bpm diff --git a/src/threading/impl/PosixMutexImpl.i b/src/threading/impl/PosixMutexImpl.i deleted file mode 100644 index c61a7b3a5210a65532e20f76094f2f26b38eac80..0000000000000000000000000000000000000000 --- a/src/threading/impl/PosixMutexImpl.i +++ /dev/null @@ -1,138 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -namespace bpm { - -// **************************************************************************** -// BPM NULL MUTEX IMPL -// **************************************************************************** -// ---------------------------------------------------------------------------- -// NullMutex::lock -// ---------------------------------------------------------------------------- -INLINE_IMPL void NullMutex::lock (void) -{ - //- noop -} - -// ---------------------------------------------------------------------------- -// NullMutex::acquire -// ---------------------------------------------------------------------------- -INLINE_IMPL void NullMutex::acquire (void) -{ - //- noop -} - -// ---------------------------------------------------------------------------- -// NullMutex::unlock -// ---------------------------------------------------------------------------- -INLINE_IMPL void NullMutex::unlock (void) -{ - //- noop -} - -// ---------------------------------------------------------------------------- -// NullMutex::release -// ---------------------------------------------------------------------------- -INLINE_IMPL void NullMutex::release (void) -{ - //- noop -} - -// ---------------------------------------------------------------------------- -// NullMutex::try_lock -// ---------------------------------------------------------------------------- -INLINE_IMPL MutexState NullMutex::try_lock (void) -{ - return bpm::MUTEX_LOCKED; -} - -// ---------------------------------------------------------------------------- -// NullMutex::try_acquire -// ---------------------------------------------------------------------------- -INLINE_IMPL MutexState NullMutex::try_acquire (void) -{ - return bpm::MUTEX_LOCKED; -} - -// **************************************************************************** -// BPM MUTEX IMPL -// **************************************************************************** -// ---------------------------------------------------------------------------- -// Mutex::lock -// ---------------------------------------------------------------------------- -INLINE_IMPL void Mutex::lock (void) -{ - ::pthread_mutex_lock(&m_posix_mux); -} -// ---------------------------------------------------------------------------- -// Mutex::acquire -// ---------------------------------------------------------------------------- -INLINE_IMPL void Mutex::acquire (void) -{ - this->lock(); -} - -// ---------------------------------------------------------------------------- -// Mutex::try_acquire -// ---------------------------------------------------------------------------- -INLINE_IMPL MutexState Mutex::try_acquire (void) -{ - return this->try_lock(); -} - -// ---------------------------------------------------------------------------- -// Mutex::unlock -// ---------------------------------------------------------------------------- -INLINE_IMPL void Mutex::unlock (void) -{ - ::pthread_mutex_unlock(&m_posix_mux); -} - -// ---------------------------------------------------------------------------- -// Mutex::acquire -// ---------------------------------------------------------------------------- -INLINE_IMPL void Mutex::release (void) -{ - this->unlock(); -} - -// ---------------------------------------------------------------------------- -// Mutex::try_lock -// ---------------------------------------------------------------------------- -INLINE_IMPL MutexState Mutex::try_lock (void) -{ - MutexState result = MUTEX_LOCKED; - - if (::pthread_mutex_trylock (&m_posix_mux) != 0) - result = MUTEX_BUSY; - - return result; -} - -} // namespace bpm diff --git a/src/threading/impl/PosixSemaphoreImpl.i b/src/threading/impl/PosixSemaphoreImpl.i deleted file mode 100644 index 125112e89b2779187ee7e04f990f98df7d87cec8..0000000000000000000000000000000000000000 --- a/src/threading/impl/PosixSemaphoreImpl.i +++ /dev/null @@ -1,90 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -namespace bpm { - -// ---------------------------------------------------------------------------- -// Semaphore::wait -// ---------------------------------------------------------------------------- -INLINE_IMPL void Semaphore::wait (void) -{ - this->timed_wait(0); -} - -// ---------------------------------------------------------------------------- -// Semaphore::timed_wait -// ---------------------------------------------------------------------------- -INLINE_IMPL bool Semaphore::timed_wait (unsigned long _tmo_msecs) -{ - bool r = false; - this->m_mux.lock(); - while (! this->m_value) - { - r = this->m_cond.timed_wait(_tmo_msecs); - } - if (r) - { - this->m_value--; - } - this->m_mux.unlock(); - return r; -} - -// ---------------------------------------------------------------------------- -// Semaphore::try_wait -// ---------------------------------------------------------------------------- -INLINE_IMPL SemaphoreState Semaphore::try_wait (void) -{ - SemaphoreState s; - this->m_mux.lock(); - if (this->m_value > 0) - { - this->m_value--; - s = SEMAPHORE_DEC; - } - else - { - s = SEMAPHORE_NO_RSC; - } - this->m_mux.unlock(); - return s; -} - -// ---------------------------------------------------------------------------- -// Semaphore::post -// ---------------------------------------------------------------------------- -INLINE_IMPL void Semaphore::post (void) -{ - this->m_mux.lock(); - this->m_value++; - this->m_cond.signal(); - this->m_mux.unlock(); -} - -} // namespace bpm diff --git a/src/threading/impl/PosixThreadImpl.i b/src/threading/impl/PosixThreadImpl.i deleted file mode 100644 index 346b9f2c56b865fdb53b6db0d848d62c733e2240..0000000000000000000000000000000000000000 --- a/src/threading/impl/PosixThreadImpl.i +++ /dev/null @@ -1,104 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -namespace bpm { - -// ---------------------------------------------------------------------------- -// Thread::priority -// ---------------------------------------------------------------------------- -INLINE_IMPL Thread::Priority Thread::priority (void) -{ - //- enter critical section - bpm::MutexLock guard(this->m_lock); - - return this->m_priority; -} -// ---------------------------------------------------------------------------- -// Thread::state -// ---------------------------------------------------------------------------- -INLINE_IMPL Thread::State Thread::state (void) -{ - //- enter critical section - bpm::MutexLock guard(this->m_lock); - - return this->m_state; -} -// ---------------------------------------------------------------------------- -// Thread::state -// ---------------------------------------------------------------------------- -INLINE_IMPL Thread::State Thread::state_i (void) const -{ - return this->m_state; -} -// ---------------------------------------------------------------------------- -// Thread::yield -// ---------------------------------------------------------------------------- -INLINE_IMPL void Thread::yield (void) -{ - ::sched_yield(); -} -// ---------------------------------------------------------------------------- -// Thread::sleep -// ---------------------------------------------------------------------------- -INLINE_IMPL void Thread::sleep (unsigned long _msecs) -{ -#define kNSECS_PER_SEC 1000000000 -#define kNSECS_PER_MSEC 1000000 - - unsigned long secs = 0; - unsigned long nanosecs = kNSECS_PER_MSEC * _msecs; - - while (nanosecs >= kNSECS_PER_SEC) - { - secs += 1; - nanosecs -= kNSECS_PER_SEC; - } - - ThreadingUtilities::sleep(secs, nanosecs); - -#undef kNSECS_PER_MSEC -#undef kNSECS_PER_SEC -} -// ---------------------------------------------------------------------------- -// Thread::self -// ---------------------------------------------------------------------------- -INLINE_IMPL ThreadUID Thread::self (void) const -{ - return this->m_uid; -} - -// ---------------------------------------------------------------------------- -// Thread::lock -// ---------------------------------------------------------------------------- -INLINE_IMPL Mutex & Thread::lock (void) -{ - return this->m_lock; -} - -} // namespace bpm diff --git a/src/threading/impl/PosixThreadingImpl.cpp b/src/threading/impl/PosixThreadingImpl.cpp deleted file mode 100644 index 9475a7887d83c1799ff6eb2a12c3b314b067accd..0000000000000000000000000000000000000000 --- a/src/threading/impl/PosixThreadingImpl.cpp +++ /dev/null @@ -1,561 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -// ============================================================================ -// DEPENDENCIES -// ============================================================================ -#include <errno.h> -#include <sys/time.h> -#include "CommonHeader.h" -#include "threading/Utilities.h" -#include "threading/Mutex.h" -#include "threading/Condition.h" -#include "threading/Semaphore.h" -#include "threading/Thread.h" - -#if ! defined (__INLINE_IMPL__) -# include "threading/impl/PosixMutexImpl.i" -# include "threading/impl/PosixConditionImpl.i" -# include "threading/impl/PosixSemaphoreImpl.i" -# include "threading/impl/PosixThreadImpl.i" -#endif - -// ============================================================================ -// SOME PSEUDO CONSTs -// ============================================================================ -#define MAX_SLEEP_SECONDS (long)4294966 //- this is (2^32 - 2) / 1000 -#define NANOSECS_PER_SEC 1000000000L -#define ONE_SEC_IN_MSECS 1000L - -// ============================================================================ -// PLATFORM SPECIFIC THREAD PRIORITIES -// ============================================================================ -#if defined(HAS_THREAD_PRIORITY) - static int lowest_priority; - static int normal_priority; - static int highest_priority; -#endif - -namespace bpm { - -// **************************************************************************** -// BPM DUMMY_MUTEX IMPL -// **************************************************************************** -// ============================================================================ -// NullMutex::NullMutex -// ============================================================================ -NullMutex::NullMutex (void) -{ - //- noop -} -// ============================================================================ -// NullMutex::~NullMutex -// ============================================================================ -NullMutex::~NullMutex (void) -{ - //- noop -} - -// **************************************************************************** -// BPM MUTEX IMPL -// **************************************************************************** -// ============================================================================ -// Mutex::Mutex -// ============================================================================ -Mutex::Mutex (void) - : m_posix_mux () -{ - pthread_mutexattr_t ma; - ::pthread_mutexattr_init(&ma); - ::pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE); - ::pthread_mutex_init(&m_posix_mux, &ma); - ::pthread_mutexattr_destroy(&ma); -} - -// ============================================================================ -// Mutex::~Mutex -// ============================================================================ -Mutex::~Mutex(void) -{ - ::pthread_mutex_destroy(&m_posix_mux); -} - -// **************************************************************************** -// BPM SEMAPHORE IMPL -// **************************************************************************** -#define SEMAPHORE_MAX_COUNT 0x7fffffff - -// ============================================================================ -// Semaphore::Semaphore -// ============================================================================ -Semaphore::Semaphore (unsigned int _initial_value) - : m_mux () , m_cond (m_mux), m_value (_initial_value) -{ - //- noop -} - -// ============================================================================ -// Semaphore::~Semaphore -// ============================================================================ -Semaphore::~Semaphore(void) -{ - //- noop -} - -// **************************************************************************** -// BPM CONDITION IMPL -// **************************************************************************** -// ============================================================================ -// Condition::Condition -// ============================================================================ -Condition::Condition (Mutex & external_lock) - : m_external_lock (external_lock), - m_posix_cond () -{ - ::pthread_cond_init(&m_posix_cond, 0); -} - -// ============================================================================ -// Condition::~Condition -// ============================================================================ -Condition::~Condition (void) -{ - ::pthread_cond_destroy(&m_posix_cond); -} - -// ============================================================================ -// Condition::timed_wait -// ============================================================================ -bool Condition::timed_wait (unsigned long _tmo_msecs) -{ - //- null tmo means infinite wait - - bool signaled = true; - - if (_tmo_msecs <= 0) - { - ::pthread_cond_wait(&m_posix_cond, &m_external_lock.m_posix_mux); - } - else - { - //- get absoulte time - struct timespec ts; - ThreadingUtilities::get_time(_tmo_msecs, ts); - - //- wait for the condition to be signaled or tmo expiration - int result = ::pthread_cond_timedwait(&m_posix_cond, - &m_external_lock.m_posix_mux, - &ts); - - if (result == ETIMEDOUT || result == EINTR) - signaled = false; - - /* - switch (result) - { - case 0: - std::cout << "Condition::pthread_cond_timedwait returned: SUCCESS" << std::endl; - break; - case ETIMEDOUT: - std::cout << "Condition::pthread_cond_timedwait returned: ETIMEDOUT" << std::endl; - break; - case EINTR: - std::cout << "Condition::pthread_cond_timedwait returned: EINTR" << std::endl; - break; - } - */ - } - - return signaled; -} - -// **************************************************************************** -// BPM THREAD IMPL -// **************************************************************************** -// ============================================================================ -// BPM common thread entry point (non-OO OS intertace to OO BPM interface) -// ============================================================================ -Thread::IOArg bpm_thread_common_entry_point (Thread::IOArg _p) -{ - //- check input (parano. impl.) - if (! _p) return 0; - - //- reinterpret input - Thread * me = reinterpret_cast<Thread*>(_p); - - //- store the thread identifier - me->m_uid = ThreadingUtilities::self(); - - //- select detached or undetached mode - if (me->m_detached) - { - //- just protect bpm impl. against user code using a try/catch statement - try - { - me->run(me->m_iarg); - } - catch (...) - { - //- ignore any exception - } - } - else - { - //- just protect bpm impl. against user code using a try/catch statement - try - { - me->m_oarg = me->run_undetached(me->m_iarg); - } - catch (...) - { - //- ignore any exception - - } - } - - //- set state to terminated - { - //- must lock the mutex even in the case of a detached thread. This is because - //- a thread may run to completion before the thread that created it has had a - //- chance to get out of start(). By locking the mutex we ensure that the - //- creating thread must have reached the end of start() before we delete the - //- thread object. Of course, once the call to start() returns, the user can - //- still incorrectly refer to the thread object, but that's his problem! - AutoMutex<Mutex> guard(me->m_lock); - //- set state to TERMINATED - me->m_state = bpm::Thread::STATE_TERMINATED; - } - - //- commit suicide in case the thread ran detached - if (me->m_detached) - delete me; - - return 0; -} - -// ============================================================================ -// Thread::Thread -// ============================================================================ -Thread::Thread (Tango::DeviceImpl * hd, Thread::IOArg _iarg, Thread::Priority _p) - : Tango::LogAdapter (hd), - m_state (bpm::Thread::STATE_NEW), - m_priority (_p), - m_iarg (_iarg), - m_oarg (0), - m_detached (true), - m_uid (BPM_INVALID_THREAD_UID), - //- platform specific members - m_posix_thread (0) -{ -#if defined(HAS_THREAD_PRIORITY) - static bool init_done = false; - if (! init_done) - { - lowest_priority = ::sched_get_priority_min(SCHED_FIFO); - highest_priority = ::sched_get_priority_max(SCHED_FIFO); - switch (highest_priority - lowest_priority) - { - case 0: - case 1: - normal_priority = lowest_priority; - break; - default: - normal_priority = lowest_priority + 1; - break; - } - init_done = true; - } -#endif -} - -// ============================================================================ -// Thread::~Thread -// ============================================================================ -Thread::~Thread (void) -{ - //- noop -} - -// ============================================================================ -// Thread::start [detatched thread] -// ============================================================================ -void Thread::start (void) - throw (Tango::DevFailed) -{ - //- mark the thread as detached - this->m_detached = true; - //- then spawn it - this->spawn(); -} - -// ============================================================================ -// Thread::start_undetached [undetatched thread] -// ============================================================================ -void Thread::start_undetached (void) - throw (Tango::DevFailed) -{ - //- mark the thread as undetached - this->m_detached = false; - //- then spawn it - this->spawn(); -} - -// ============================================================================ -// Thread::spawn (common to detatched & undetached threads) -// ============================================================================ -void Thread::spawn (void) - throw (Tango::DevFailed) -{ - //- enter critical section - AutoMutex<Mutex> guard(this->m_lock); - - //- be sure the thread is not already running or terminated - if (this->m_state != bpm::Thread::STATE_NEW) - return; - - //- intialize thread attributes - pthread_attr_t thread_attrs; - - ::pthread_attr_init(&thread_attrs); - - //- set detach attribute - int ds = this->m_detached - ? PTHREAD_CREATE_DETACHED - : PTHREAD_CREATE_JOINABLE; - ::pthread_attr_setdetachstate(&thread_attrs, ds); - - //- set thread priority -#if defined(HAS_THREAD_PRIORITY) - struct sched_param sp; - sp.sched_priority = bpm_to_posix_priority(m_priority); - ::pthread_attr_setschedparam(&thread_attrs, &sp)); -#endif - - //- spawn the thread - int result = 0; - result = ::pthread_create(&m_posix_thread, - &thread_attrs, - bpm_thread_common_entry_point, - static_cast<void*>(this)); - ::pthread_attr_destroy(&thread_attrs); - - //- check result - if (result) - Tango::Except::throw_exception(_CPTC("INTERNAL_ERROR"), - _CPTC("system call <pthread_create> failed"), - _CPTC("Thread::spawn")); - - //- mark the thread as running (before leaving the critical section) - this->m_state = bpm::Thread::STATE_RUNNING; -} - -// ============================================================================ -// Thread::join -// ============================================================================ -void Thread::join (Thread::IOArg * oarg_) - throw (Tango::DevFailed) -{ - { - //- enter critical section - AutoMutex<Mutex> guard(this->m_lock); - - //- check thread state - if ( - (this->m_state != bpm::Thread::STATE_RUNNING) - && - (this->m_state != bpm::Thread::STATE_TERMINATED) - ) - Tango::Except::throw_exception(_CPTC("PROGRAMMING_ERROR"), - _CPTC("can't join [thread never started or already terminated]"), - _CPTC("Thread::join")); - } - - //- be sure the thread is not detached - if (this->m_detached) - Tango::Except::throw_exception(_CPTC("PROGRAMMING_ERROR"), - _CPTC("can't join with a detached thread"), - _CPTC("Thread::join")); - - if (::pthread_join(m_posix_thread, 0)) - Tango::Except::throw_exception(_CPTC("INTERNAL_ERROR"), - _CPTC("system call <pthread_join> failed"), - _CPTC("Thread::join")); - - //- return the "thread result" - if (oarg_) - *oarg_ = this->m_oarg; - - //- commit suicide - delete this; -} - -// ============================================================================ -// Thread::priority -// ============================================================================ -void Thread::priority (Priority _p) - throw (Tango::DevFailed) -{ - //- enter critical section - AutoMutex<Mutex> guard(this->m_lock); - - //- check thread state - if (this->m_state != bpm::Thread::STATE_RUNNING) - return; //- throw exception - -#if defined(HAS_THREAD_PRIORITY) - struct sched_param sp; - sp.sched_priority = this->bpm_to_posix_priority(_p); - if (::pthread_setschedparam(m_posix_thread, SCHED_OTHER, &sp)) - Tango::Except::throw_exception(_CPTC("INTERNAL_ERROR"), - _CPTC("system call <pthread_setschedparam> failed"), - _CPTC("Thread::priority")); -#endif - - //- store new priority - this->m_priority = _p; -} - -// ============================================================================ -// Thread::bpm_to_posix_priority -// ============================================================================ -int Thread::bpm_to_posix_priority (Priority _p) -{ -#if defined(HAS_THREAD_PRIORITY) - switch (_p) - { - case bpm::Thread::PRIORITY_LOW: - return lowest_priority; - break; - case bpm::Thread::PRIORITY_HIGH: - return highest_priority; - break; - case bpm::Thread::PRIORITY_RT: - return highest_priority; - break; - default: - return normal_priority; - } -#else - switch (_p) - { - default: - return 0; - } -#endif -} - - -// ============================================================================ -// ThreadingUtilities::self -// ============================================================================ -ThreadUID ThreadingUtilities::self (void) -{ - return static_cast<bpm::ThreadUID>(::pthread_self()); -} - -// ============================================================================ -// ThreadingUtilities::sleep -// ============================================================================ -void ThreadingUtilities::sleep (unsigned long _secs, unsigned long _nano_secs) -{ -#if defined(HAS_NANO_SLEEP) - - timespec ts2; - timespec ts1 = {_secs, _nano_secs}; - - while (::nanosleep(&ts1, &ts2)) - { - if (errno == EINTR) - { - ts1.tv_sec = ts2.tv_sec; - ts1.tv_nsec = ts2.tv_nsec; - continue; - } - } - -#else - - if (_secs > 2000) - while ((_secs = ::sleep(_secs))) ; - else - ::usleep(_secs * 1000000 + (_nano_secs / 1000)); - -#endif -} - -// ============================================================================ -// ThreadingUtilities::get_time -// ============================================================================ -void ThreadingUtilities::get_time (unsigned long & abs_sec_, - unsigned long & abs_nano_sec_, - unsigned long _rel_sec, - unsigned long _rel_nano_sec) -{ - timespec abs; - - struct timeval tv; - ::gettimeofday(&tv, NULL); - - abs.tv_sec = tv.tv_sec; - abs.tv_nsec = tv.tv_usec * 1000; - - abs.tv_sec += _rel_sec + abs.tv_nsec / NANOSECS_PER_SEC; - abs.tv_nsec += _rel_nano_sec; - abs.tv_nsec %= NANOSECS_PER_SEC; - - abs_sec_ = abs.tv_sec; - abs_nano_sec_ = abs.tv_nsec; -} - -// ============================================================================ -// ThreadingUtilities::get_time -// ============================================================================ -void ThreadingUtilities::get_time (unsigned long delay_msecs, Timespec& abs_time) -{ - struct timeval now; - ::gettimeofday(&now, NULL); - - //- std::cout << "delay_msecs........" << delay_msecs << std::endl; - - abs_time.tv_sec = now.tv_sec + delay_msecs / 1000; - delay_msecs -= delay_msecs / 1000 * 1000; - abs_time.tv_nsec = now.tv_usec * 1000; - abs_time.tv_nsec += delay_msecs * 1000000; - abs_time.tv_sec += abs_time.tv_nsec / NANOSECS_PER_SEC; - abs_time.tv_nsec %= NANOSECS_PER_SEC; - - //- std::cout << "now.tv_sec........." << now.tv_sec << std::endl; - //- std::cout << "now.tv_nsec........" << now.tv_usec * 1000 << std::endl; - //- std::cout << "abs_time.tv_sec...." << abs_time.tv_sec << std::endl; - //- std::cout << "abs_time.tv_nsec..." << abs_time.tv_nsec << std::endl; - //- std::cout << "dt.sec............." << abs_time.tv_sec - now.tv_sec << std::endl; - //- std::cout << "dt.nsec............" << abs_time.tv_nsec - (now.tv_usec * 1000) << std::endl; -} - -} // namespace bpm diff --git a/src/threading/impl/PosixThreadingImpl.h b/src/threading/impl/PosixThreadingImpl.h deleted file mode 100644 index 4b2447ff5cf54524a88164498c828759f955eefc..0000000000000000000000000000000000000000 --- a/src/threading/impl/PosixThreadingImpl.h +++ /dev/null @@ -1,75 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -#ifndef _POSIX_THREADING_IMPL_ -#define _POSIX_THREADING_IMPL_ - -//- no nano sleep! -//- #define HAS_NANO_SLEEP - -//- no thread priority! -//- #define HAS_THREAD_PRIORITY - -// ---------------------------------------------------------------------------- -// MUTEX - MUTEX - MUTEX - MUTEX - MUTEX - MUTEX - MUTEX - MUTEX - MUTEX -// ---------------------------------------------------------------------------- -#define __MUTEX_IMPLEMENTATION \ - pthread_mutex_t m_posix_mux; \ - friend class Condition; - -// ---------------------------------------------------------------------------- -// CONDITION - CONDITION - CONDITION - CONDITION - CONDITION - CONDITION -// ---------------------------------------------------------------------------- -#define __CONDITION_IMPLEMENTATION \ - pthread_cond_t m_posix_cond; - -// ---------------------------------------------------------------------------- -// SEMAPHORE - SEMAPHORE - SEMAPHORE - SEMAPHORE - SEMAPHORE - SEMAPHORE -// ---------------------------------------------------------------------------- -#define __SEMAPHORE_IMPLEMENTATION \ - Mutex m_mux; \ - Condition m_cond; \ - int m_value; - -// ---------------------------------------------------------------------------- -// THREAD - THREAD - THREAD - THREAD - THREAD - THREAD - THREAD - THREAD -// ---------------------------------------------------------------------------- -//- common thread entry point (non-OO OS interface to interface) -#define THREAD_COMMON_ENTRY_POINT \ - void * bpm_thread_common_entry_point (void *) - -extern "C" THREAD_COMMON_ENTRY_POINT; - -#define __THREAD_IMPLEMENTATION \ - pthread_t m_posix_thread; \ - void spawn (void) throw (Tango::DevFailed); \ - static int bpm_to_posix_priority (Priority); \ - friend THREAD_COMMON_ENTRY_POINT; - -#endif //- _POSIX_THREADING_IMPL_ diff --git a/src/threading/impl/PosixThreadingImpl.i b/src/threading/impl/PosixThreadingImpl.i deleted file mode 100644 index 5d45bf1be53d97b90aae37d921b2ad8034e8e6b1..0000000000000000000000000000000000000000 --- a/src/threading/impl/PosixThreadingImpl.i +++ /dev/null @@ -1,169 +0,0 @@ -//------------------------------------------------------------------------------ -// This file is part of the Libera Tango Device -//------------------------------------------------------------------------------ -// -// Copyright (C) 2005-2008 Nicolas Leclercq, Synchrotron SOLEIL. -// -// Part of the code is copyright (C) 2005-2008 Michael Abbott, -// Diamond Light Source Ltd. See ./ma/README for details. -// -// The Libera Tango Device is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or (at your -// option) any later version. -// -// The Libera Tango Device 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 General -// Public License for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., 51 -// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// -// Contact: -// Nicolas Leclercq -// Synchrotron SOLEIL -// libera-sofware<AT>esrf<DOT>fr -//------------------------------------------------------------------------------ - -namespace bpm { - -// **************************************************************************** -// YAT DUMMY_MUTEX IMPL -// **************************************************************************** -// ---------------------------------------------------------------------------- -// DummyMutex::lock -// ---------------------------------------------------------------------------- -INLINE_IMPL void DummyMutex::lock (void) -{ - //- noop -} -// ---------------------------------------------------------------------------- -// DummyMutex::acquire -// ---------------------------------------------------------------------------- -INLINE_IMPL void DummyMutex::acquire (void) -{ - //- noop -} -// ---------------------------------------------------------------------------- -// DummyMutex::unlock -// ---------------------------------------------------------------------------- -INLINE_IMPL void DummyMutex::unlock (void) -{ - //- noop -} -// ---------------------------------------------------------------------------- -// DummyMutex::release -// ---------------------------------------------------------------------------- -INLINE_IMPL void DummyMutex::release (void) -{ - //- noop -} -// ---------------------------------------------------------------------------- -// DummyMutex::try_lock -// ---------------------------------------------------------------------------- -INLINE_IMPL MutexState DummyMutex::try_lock (void) -{ - return bpm::MUTEX_LOCKED; -} -// ---------------------------------------------------------------------------- -// DummyMutex::try_acquire -// ---------------------------------------------------------------------------- -INLINE_IMPL MutexState DummyMutex::try_acquire (void) -{ - return bpm::MUTEX_LOCKED; -} - -// **************************************************************************** -// YAT MUTEX IMPL -// **************************************************************************** -// ---------------------------------------------------------------------------- -// Mutex::lock -// ---------------------------------------------------------------------------- -INLINE_IMPL void Mutex::lock (void) -{ -#error no impl -} -// ---------------------------------------------------------------------------- -// Mutex::acquire -// ---------------------------------------------------------------------------- -INLINE_IMPL void Mutex::acquire (void) -{ - this->lock(); -} -// ---------------------------------------------------------------------------- -// Mutex::try_acquire -// ---------------------------------------------------------------------------- -MutexState Mutex::try_acquire (void) -{ - return this->try_lock(); -} -// ---------------------------------------------------------------------------- -// Mutex::unlock -// ---------------------------------------------------------------------------- -INLINE_IMPL void Mutex::unlock (void) -{ -#error no impl -} -// ---------------------------------------------------------------------------- -// Mutex::acquire -// ---------------------------------------------------------------------------- -INLINE_IMPL void Mutex::release (void) -{ - this->unlock(); -} - -// **************************************************************************** -// YAT THREAD IMPL -// **************************************************************************** -// ---------------------------------------------------------------------------- -// Thread::priority -// ---------------------------------------------------------------------------- -INLINE_IMPL Priority Thread::priority (void) const -{ - //- enter critical section - bpm::SmartMutex guard(this->m_lock); - - return this->m_priority; -} -// ---------------------------------------------------------------------------- -// Thread::state -// ---------------------------------------------------------------------------- -INLINE_IMPL State Thread::state (void) const -{ - //- enter critical section - bpm::SmartMutex guard(this->m_lock); - - return this->m_state; -} -// ---------------------------------------------------------------------------- -// Thread::yield -// ---------------------------------------------------------------------------- -INLINE_IMPL void Thread::yield (void) -{ -#error no impl -} -// ---------------------------------------------------------------------------- -// Thread::sleep -// ---------------------------------------------------------------------------- -INLINE_IMPL void Thread::sleep (unsigned long _tmo_msecs) -{ - ThreadingUtilities::sleep(0, 1000000 * _tmo_msecs); -} -// ---------------------------------------------------------------------------- -// Thread::self -// ---------------------------------------------------------------------------- -INLINE_IMPL ThreadUID Thread::self (void) const -{ - return this->m_uid; -} -// ---------------------------------------------------------------------------- -// Thread::lock -// ---------------------------------------------------------------------------- -INLINE_IMPL Thread::Mutex & lock (void) const -{ - return this->m_lock; -} - -} // namespace bpm