]> granicus.if.org Git - icinga2/commitdiff
Implemented Lock class.
authorGunnar Beutner <gunnar.beutner@netways.de>
Thu, 17 May 2012 18:34:51 +0000 (20:34 +0200)
committerGunnar Beutner <gunnar.beutner@netways.de>
Fri, 18 May 2012 08:15:15 +0000 (10:15 +0200)
base/Makefile.am
base/base.vcxproj
base/condvar.cpp
base/condvar.h
base/i2-base.h
base/lock.cpp [new file with mode: 0644]
base/lock.h [new file with mode: 0644]
base/object.h
base/observable.h [new file with mode: 0644]

index 601d09d502f573fa876d6ca07673fd9d3dc68471..daa171ce8ef082b52d8f0a66d1689e84807e098c 100644 (file)
@@ -27,6 +27,8 @@ libbase_la_SOURCES =  \
        fifo.cpp \
        fifo.h \
        i2-base.h \
+       lock.cpp \
+       lock.h \
        memory.cpp \
        memory.h \
        mutex.cpp \
index bdcca97adcdc008f186a4214771909c73009c8a6..44e415aea3606b429a5d56e30e5cd18a1d37ab4e 100644 (file)
@@ -20,6 +20,7 @@
     <ClCompile Include="dictionary.cpp" />
     <ClCompile Include="exception.cpp" />
     <ClCompile Include="fifo.cpp" />
+    <ClCompile Include="lock.cpp" />
     <ClCompile Include="memory.cpp" />
     <ClCompile Include="mutex.cpp" />
     <ClCompile Include="object.cpp" />
@@ -45,6 +46,7 @@
     <ClInclude Include="cxx11-compat.h" />
     <ClInclude Include="delegate.h" />
     <ClInclude Include="dictionary.h" />
+    <ClInclude Include="lock.h" />
     <ClInclude Include="observable.h" />
     <ClInclude Include="exception.h" />
     <ClInclude Include="fifo.h" />
index bc072ff24e7dfc0f794dc630b80b3dba3bcf0a2c..01d1b754d97c145ef7751325f064855efa327073 100644 (file)
@@ -50,13 +50,41 @@ CondVar::~CondVar(void)
  * before it begins to wait and re-acquires the mutex after waiting.
  *
  * @param mtx The mutex that should be released during waiting.
+ * @param timeoutMilliseconds The timeout in milliseconds. Use the special
+ *                            constant CondVar::TimeoutInfinite for an
+ *                            infinite timeout.
+ * @returns false if a timeout occured, true otherwise.
  */
-void CondVar::Wait(Mutex& mtx)
+bool CondVar::Wait(Mutex& mtx, WaitTimeout timeoutMilliseconds)
 {
 #ifdef _WIN32
-       SleepConditionVariableCS(&m_CondVar, mtx.Get(), INFINITE);
+       return (SleepConditionVariableCS(&m_CondVar, mtx.Get(),
+           timeoutMilliseconds) != FALSE);
 #else /* _WIN32 */
-       pthread_cond_wait(&m_CondVar, mtx.Get());
+       if (timeoutMilliseconds == TimeoutInfinite)
+               pthread_cond_wait(&m_CondVar, mtx.Get());
+       else {
+               timeval now;
+               timespec ts;
+
+               if (gettimeofday(&now, NULL) < 0)
+                       throw PosixException("gettimeofday failed.", errno);
+
+               ts.tv_sec = now.tv_sec;
+               ts.tv_nsec = now.tv_usec * 1000;
+               ts.tv_nsec += timeoutMilliseconds * 1000;
+
+               int rc = pthread_cond_timedwait(&m_CondVar, mtx.Get(), &ts);
+
+               if (rc == 0)
+                       return true;
+
+               if (errno != ETIMEDOUT)
+                       throw PosixException("pthread_cond_timedwait failed",
+                           errno);
+
+               return false;
+       }
 #endif /* _WIN32 */
 }
 
index 6b63d3be949bdf6f5c9f771b6be459a4a14ccd7f..b8cbcd41bee1d58744b9799c911ee998c225b8ab 100644 (file)
@@ -36,10 +36,18 @@ private:
 #endif /* _WIN32 */
 
 public:
+#ifdef _WIN32
+       typedef DWORD WaitTimeout;
+       static const WaitTimeout TimeoutInfinite = INFINITE;
+#else /* _WIN32 */
+       typedef int WaitTimeout;
+       static const WaitTimeout TimeoutInfinite = -1;
+#endif /* _WIN32 */
+
        CondVar(void);
        ~CondVar(void);
 
-       void Wait(Mutex& mtx);
+       bool Wait(Mutex& mtx, WaitTimeout timeoutMilliseconds = TimeoutInfinite);
        void Signal(void);
        void Broadcast(void);
 
index 985565e89e21c22153fd9d579f227179b1bc49f3..5dba56915589681f3f75f60aba25076dab05a53c 100644 (file)
@@ -96,6 +96,7 @@ using namespace std::tr1::placeholders;
 #endif /* I2_BASE_BUILD */
 
 #include "mutex.h"
+#include "lock.h"
 #include "condvar.h"
 #include "thread.h"
 #include "utility.h"
diff --git a/base/lock.cpp b/base/lock.cpp
new file mode 100644 (file)
index 0000000..fd93adc
--- /dev/null
@@ -0,0 +1,40 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/)        *
+ *                                                                            *
+ * This program 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.                     *
+ *                                                                            *
+ * This program 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.             *
+ ******************************************************************************/
+
+#include "i2-base.h"
+
+using namespace icinga;
+
+/**
+ * Constructor for the Lock class. Acquires a lock on the specified mutex.
+ *
+ * @param mutex The mutex that is to be locked.
+ */
+Lock::Lock(Mutex& mutex) : m_Mutex(mutex)
+{
+       m_Mutex.Exit();
+}
+
+/**
+ * Destructor for the Lock class. Releases the lock.
+ */
+Lock::~Lock(void)
+{
+       m_Mutex.Exit();
+}
diff --git a/base/lock.h b/base/lock.h
new file mode 100644 (file)
index 0000000..62db329
--- /dev/null
@@ -0,0 +1,42 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/)        *
+ *                                                                            *
+ * This program 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.                     *
+ *                                                                            *
+ * This program 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.             *
+ ******************************************************************************/
+
+#ifndef LOCK_H
+#define LOCK_H
+
+namespace icinga
+{
+
+/**
+ * A lock that is held on a mutex and automatically released when the Lock
+ * object is destroyed.
+ */
+class I2_BASE_API Lock
+{
+private:
+       Mutex& m_Mutex;
+
+public:
+       Lock(Mutex& mutex);
+       ~Lock(void);
+};
+
+}
+
+#endif /* LOCK_H */
index 5b7776c024499445d78f4e9be17dafc2895e41ce..cf054a77c25f5fea6e15296df3e506d105d4c06b 100644 (file)
@@ -31,6 +31,7 @@ class I2_BASE_API Object : public enable_shared_from_this<Object>
 {
 private:
        Object(const Object& other);
+       Object operator=(const Object& rhs);
 
 protected:
        Object(void);
diff --git a/base/observable.h b/base/observable.h
new file mode 100644 (file)
index 0000000..c9edfd8
--- /dev/null
@@ -0,0 +1,92 @@
+/******************************************************************************
+ * Icinga 2                                                                   *
+ * Copyright (C) 2012 Icinga Development Team (http://www.icinga.org/)        *
+ *                                                                            *
+ * This program 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.                     *
+ *                                                                            *
+ * This program 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.             *
+ ******************************************************************************/
+
+#ifndef OBSERVABLE_H
+#define OBSERVABLE_H
+
+namespace icinga
+{
+
+/**
+ * Base class for event arguments.
+ */
+struct I2_BASE_API EventArgs
+{
+       Object::Ptr Source; /**< The source of the event. */
+};
+
+/**
+ * An observable event. Observers can be registered for it.
+ */
+template<class TArgs>
+class Observable
+{
+public:
+       typedef function<int (const TArgs&)> ObserverType;
+
+private:
+       vector<ObserverType> m_Observers;
+
+public:
+       /**
+        * Adds an observer to this event.
+        *
+        * @param rhs The delegate.
+        */
+       Observable<TArgs>& operator +=(const ObserverType& rhs)
+       {
+               m_Observers.push_back(rhs);
+               return *this;
+       }
+
+       /**
+        * Removes an observer from this event.
+        *
+        * @param rhs The delegate.
+        */
+       Observable<TArgs>& operator -=(const ObserverType& rhs)
+       {
+               m_Observers.erase(rhs);
+               return *this;
+       }
+
+       /**
+        * Invokes each observer function that is registered for this event. Any
+        * observer function which returns -1 is removed.
+        *
+        * @param args Event arguments.
+        */
+       void operator()(const TArgs& args)
+       {
+               typename vector<ObserverType>::iterator i;
+
+               for (i = m_Observers.begin(); i != m_Observers.end(); ) {
+                       int result = (*i)(args);
+
+                       if (result == -1)
+                               i = m_Observers.erase(i);
+                       else
+                               i++;
+               }
+       }
+};
+
+}
+
+#endif /* OBSERVABLE_H */