Threading support.
[shibboleth/cpp-xmltooling.git] / xmltooling / util / Threads.h
diff --git a/xmltooling/util/Threads.h b/xmltooling/util/Threads.h
new file mode 100644 (file)
index 0000000..ef9231b
--- /dev/null
@@ -0,0 +1,309 @@
+/*\r
+ *  Copyright 2001-2006 Internet2\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/**\r
+ * @file Threads.h\r
+ * \r
+ * Thread and locking wrappers \r
+ */\r
+\r
+#ifndef _xmltooling_threads_h\r
+#define _xmltooling_threads_h\r
+\r
+#include <xmltooling/base.h>\r
+#include <xmltooling/exceptions.h>\r
+\r
+namespace xmltooling\r
+{\r
+    DECL_XMLTOOLING_EXCEPTION(ThreadingException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during threading/locking operations);\r
+    \r
+    /**\r
+     * A class for manual thread creation and synchronization.\r
+     */\r
+    class XMLTOOL_API Thread\r
+    {\r
+        MAKE_NONCOPYABLE(Thread);\r
+    public:\r
+        Thread() {}\r
+        virtual ~Thread() {}\r
+\r
+        /**\r
+         * Disassociate from the thread.\r
+         * \r
+         * @return 0 for success, non-zero for failure\r
+         */\r
+        virtual int detach()=0;\r
+        \r
+        /**\r
+         * Join with the thread and wait for its completion.\r
+         * \r
+         * @param thread_return holds the return value of the thread routine\r
+         * @return 0 for success, non-zero for failure\r
+         */\r
+        virtual int join(void** thread_return)=0;\r
+        \r
+        /**\r
+         * Kill the thread.\r
+         * \r
+         * @param signo the signal to send to the thread\r
+         * @return 0 for success, non-zero for failure\r
+         */\r
+        virtual int kill(int signo)=0;\r
+        \r
+        /**\r
+         * Creates a new thread object to run the supplied start routine.\r
+         * \r
+         * @param start_routine the function to execute on the thread\r
+         * @param arg           a parameter for the start routine\r
+         * @return  the created and running thread object \r
+         */\r
+        static Thread* create(void* (*start_routine)(void*), void* arg);\r
+        \r
+        /**\r
+         * Exits a thread gracefully.\r
+         * \r
+         * @param return_val    the return value for the thread\r
+         */\r
+        static void exit(void* return_val);\r
+        \r
+#ifndef WIN32\r
+        /**\r
+         * Masks all signals from a thread. \r
+         */\r
+        static void mask_all_signals(void);\r
+        \r
+        /**\r
+         * Masks specific signals from a thread.\r
+         * \r
+         * @param how\r
+         * @param newmask   the new signal mask\r
+         * @param oldmask   the old signal mask\r
+         * @return 0 for success, non-zero for failure\r
+         */\r
+        static int mask_signals(int how, const sigset_t *newmask, sigset_t *oldmask);\r
+#endif\r
+    };\r
+\r
+    /**\r
+     * A class for managing Thread Local Storage values.\r
+     */\r
+    class XMLTOOL_API ThreadKey\r
+    {\r
+        MAKE_NONCOPYABLE(ThreadKey);\r
+    public:\r
+        ThreadKey() {}\r
+        virtual ~ThreadKey() {}\r
+\r
+        /**\r
+         * Sets the value for a TLS key.\r
+         * \r
+         * @param data  the value to set\r
+         * @return 0 for success, non-zero for failure\r
+         */\r
+        virtual int setData(void* data)=0;\r
+\r
+        /**\r
+         * Returns the value for a TLS key.\r
+         * \r
+         * @return the value or NULL\r
+         */        \r
+        virtual void* getData() const=0;\r
+\r
+        /**\r
+         * Creates a new TLS key.\r
+         * \r
+         * @param destroy_fn    a functon to cleanup key values\r
+         * @return the new key\r
+         */\r
+        static ThreadKey* create(void (*destroy_fn)(void*));\r
+    };\r
+\r
+    /**\r
+     * A class for managing exclusive access to resources.\r
+     */\r
+    class XMLTOOL_API Mutex\r
+    {\r
+        MAKE_NONCOPYABLE(Mutex);\r
+    public:\r
+        Mutex() {}\r
+        virtual ~Mutex() {}\r
+\r
+        /**\r
+         * Locks the mutex for exclusive access.\r
+         * \r
+         * @return 0 for success, non-zero for failure\r
+         */\r
+        virtual int lock()=0;\r
+        \r
+        /**\r
+         * Unlocks the mutex for exclusive access.\r
+         * \r
+         * @return 0 for success, non-zero for failure\r
+         */\r
+        virtual int unlock()=0;\r
+\r
+        /**\r
+         * Creates a new mutex object.\r
+         * \r
+         * @return the new mutex\r
+         */\r
+        static Mutex* create();\r
+    };\r
+    \r
+    /**\r
+     * A class for managing shared and exclusive access to resources.\r
+     */\r
+    class XMLTOOL_API RWLock\r
+    {\r
+        MAKE_NONCOPYABLE(RWLock);\r
+    public:\r
+        RWLock() {}\r
+        virtual ~RWLock() {}\r
+\r
+        /**\r
+         * Obtains a shared lock.\r
+         * \r
+         * @return 0 for success, non-zero for failure\r
+         */\r
+        virtual int rdlock()=0;\r
+        \r
+        /**\r
+         * Obtains an exclusive lock.\r
+         * \r
+         * @return 0 for success, non-zero for failure\r
+         */\r
+        virtual int wrlock()=0;\r
+\r
+        /**\r
+         * Unlocks the lock.\r
+         * \r
+         * @return 0 for success, non-zero for failure\r
+         */\r
+        virtual int unlock()=0;\r
+\r
+        /**\r
+         * Creates a new read/write lock.\r
+         * \r
+         * @return the new lock\r
+         */\r
+        static RWLock* create();\r
+    };\r
+    \r
+    /**\r
+     * A class for establishing queues on a mutex based on a periodic condition.\r
+     */\r
+    class XMLTOOL_API CondWait\r
+    {\r
+        MAKE_NONCOPYABLE(CondWait);\r
+    public:\r
+        CondWait() {}\r
+        virtual ~CondWait() {}\r
+        \r
+        /**\r
+         * Waits for a condition variable using the supplied mutex as a queue.\r
+         * \r
+         * @param lock  mutex to queue on\r
+         * @return 0 for success, non-zero for failure\r
+         */\r
+        virtual int wait(Mutex* lock)=0;\r
+        \r
+        /**\r
+         * Waits for a condition variable using the supplied mutex as a queue,\r
+         * but only for a certain time limit.\r
+         * \r
+         * @param lock          mutex to queue on\r
+         * @param delay_seconds maximum time to wait before waking up\r
+         * @return 0 for success, non-zero for failure\r
+         */\r
+        virtual int timedwait(Mutex* lock, int delay_seconds)=0;\r
+        \r
+        /**\r
+         * Signal a single thread to wake up if a condition changes.\r
+         * \r
+         * @return 0 for success, non-zero for failure\r
+         */\r
+        virtual int signal()=0;\r
+        \r
+        /**\r
+         * Signal all threads to wake up if a condition changes.\r
+         * \r
+         * @return 0 for success, non-zero for failure\r
+         */\r
+        virtual int broadcast()=0;\r
+\r
+        /**\r
+         * Creates a new condition variable.\r
+         * \r
+         * @return the new condition variable\r
+         */\r
+        static CondWait* create();\r
+    };\r
+    \r
+    /**\r
+     * RAII wrapper for a mutex lock.\r
+     */\r
+    class XMLTOOL_API Lock {\r
+        MAKE_NONCOPYABLE(Lock);\r
+    public:\r
+        /**\r
+         * Locks and wraps the designated mutex.\r
+         * \r
+         * @param mtx mutex to lock \r
+         */\r
+        Lock(Mutex* mtx) : mutex(mtx) {\r
+            mutex->lock();\r
+        }\r
+        \r
+        /**\r
+         * Unlocks the wrapped mutex.\r
+         */\r
+        ~Lock() {\r
+            mutex->unlock();\r
+        }\r
+    \r
+    private:\r
+        Mutex* mutex;\r
+    };\r
+    \r
+    /**\r
+     * RAII wrapper for a shared lock.\r
+     */\r
+    class XMLTOOL_API ReadLock {\r
+        MAKE_NONCOPYABLE(ReadLock);\r
+    public:\r
+        /**\r
+         * Locks and wraps the designated shared lock.\r
+         * \r
+         * @param lock lock to acquire \r
+         */\r
+        ReadLock(RWLock* lock) : rwlock(lock) {\r
+            rwlock->rdlock();\r
+        }\r
+        \r
+        /**\r
+         * Unlocks the wrapped shared lock.\r
+         */\r
+        ~ReadLock() {\r
+            rwlock->unlock();\r
+        }\r
+    \r
+    private:\r
+        RWLock* rwlock;\r
+    };\r
+\r
+}\r
+\r
+#endif /* _xmltooling_threads_h */\r