Merge branch '1.x' of ssh://authdev.it.ohio-state.edu/~scantor/git/cpp-xmltooling...
[shibboleth/cpp-xmltooling.git] / xmltooling / util / Threads.h
index ef9231b..abb8c10 100644 (file)
-/*\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
+/**
+ * Licensed to the University Corporation for Advanced Internet
+ * Development, Inc. (UCAID) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for
+ * additional information regarding copyright ownership.
+ *
+ * UCAID licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the
+ * License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
+ */
+
+/**
+ * @file xmltooling/util/Threads.h
+ *
+ * Thread and locking wrappers.
+ */
+
+#ifndef _xmltooling_threads_h
+#define _xmltooling_threads_h
+
+#include <xmltooling/exceptions.h>
+
+#include <signal.h>
+
+namespace xmltooling
+{
+    DECL_XMLTOOLING_EXCEPTION(ThreadingException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during threading/locking operations);
+
+    /**
+     * A class for manual thread creation and synchronization.
+     */
+    class XMLTOOL_API Thread
+    {
+        MAKE_NONCOPYABLE(Thread);
+    protected:
+        Thread() {}
+    public:
+        virtual ~Thread() {}
+
+        /**
+         * Disassociate from the thread.
+         *
+         * @return 0 for success, non-zero for failure
+         */
+        virtual int detach()=0;
+
+        /**
+         * Join with the thread and wait for its completion.
+         *
+         * @param thread_return holds the return value of the thread routine
+         * @return 0 for success, non-zero for failure
+         */
+        virtual int join(void** thread_return)=0;
+
+        /**
+         * Kill the thread.
+         *
+         * @param signo the signal to send to the thread
+         * @return 0 for success, non-zero for failure
+         */
+        virtual int kill(int signo)=0;
+
+        /**
+         * Creates a new thread object to run the supplied start routine.
+         *
+         * @param start_routine the function to execute on the thread
+         * @param arg           a parameter for the start routine
+         * @param stacksize     size of stack to use, or 0 for default
+         * @return  the created and running thread object
+         */
+        static Thread* create(void* (*start_routine)(void*), void* arg, size_t stacksize=0);
+
+        /**
+         * Exits a thread gracefully.
+         *
+         * @param return_val    the return value for the thread
+         */
+        static void exit(void* return_val);
+
+        /**
+         * Sleeps the current thread for the specified amount of time.
+         *
+         * @param seconds   time to sleep
+         */
+        static void sleep(int seconds);
+#ifndef WIN32
+        /**
+         * Masks all signals from a thread.
+         */
+        static void mask_all_signals(void);
+
+        /**
+         * Masks specific signals from a thread.
+         *
+         * @param how
+         * @param newmask   the new signal mask
+         * @param oldmask   the old signal mask
+         * @return 0 for success, non-zero for failure
+         */
+        static int mask_signals(int how, const sigset_t *newmask, sigset_t *oldmask);
+#endif
+    };
+
+    /**
+     * A class for managing Thread Local Storage values.
+     */
+    class XMLTOOL_API ThreadKey
+    {
+        MAKE_NONCOPYABLE(ThreadKey);
+    protected:
+        ThreadKey() {}
+    public:
+        virtual ~ThreadKey() {}
+
+        /**
+         * Sets the value for a TLS key.
+         *
+         * @param data  the value to set
+         * @return 0 for success, non-zero for failure
+         */
+        virtual int setData(void* data)=0;
+
+        /**
+         * Returns the value for a TLS key.
+         *
+         * @return the value or nullptr
+         */
+        virtual void* getData() const=0;
+
+        /**
+         * Creates a new TLS key.
+         *
+         * @param destroy_fn    a functon to cleanup key values
+         * @return the new key
+         */
+        static ThreadKey* create(void (*destroy_fn)(void*));
+
+#ifdef WIN32
+        /**
+         * Allows system to notify TLS implementation when a thread completes.
+         *
+         * <p>Windows doesn't support TLS destructors, so only the DllMain detach
+         * notification can be used to trigger per-thread cleanup.
+         */
+        static void onDetach();
+#endif
+    };
+
+    /**
+     * A class for managing exclusive access to resources.
+     */
+    class XMLTOOL_API Mutex
+    {
+        MAKE_NONCOPYABLE(Mutex);
+    protected:
+        Mutex() {}
+    public:
+        virtual ~Mutex() {}
+
+        /**
+         * Locks the mutex for exclusive access.
+         *
+         * @return 0 for success, non-zero for failure
+         */
+        virtual int lock()=0;
+
+        /**
+         * Unlocks the mutex for exclusive access.
+         *
+         * @return 0 for success, non-zero for failure
+         */
+        virtual int unlock()=0;
+
+        /**
+         * Creates a new mutex object.
+         *
+         * @return the new mutex
+         */
+        static Mutex* create();
+    };
+
+    /**
+     * A class for managing shared and exclusive access to resources.
+     */
+    class XMLTOOL_API RWLock
+    {
+        MAKE_NONCOPYABLE(RWLock);
+    protected:
+        RWLock() {}
+    public:
+        virtual ~RWLock() {}
+
+        /**
+         * Obtains a shared lock.
+         *
+         * @return 0 for success, non-zero for failure
+         */
+        virtual int rdlock()=0;
+
+        /**
+         * Obtains an exclusive lock.
+         *
+         * @return 0 for success, non-zero for failure
+         */
+        virtual int wrlock()=0;
+
+        /**
+         * Unlocks the lock.
+         *
+         * @return 0 for success, non-zero for failure
+         */
+        virtual int unlock()=0;
+
+        /**
+         * Creates a new read/write lock.
+         *
+         * @return the new lock
+         */
+        static RWLock* create();
+    };
+
+    /**
+     * A class for establishing queues on a mutex based on a periodic condition.
+     */
+    class XMLTOOL_API CondWait
+    {
+        MAKE_NONCOPYABLE(CondWait);
+    protected:
+        CondWait() {}
+    public:
+        virtual ~CondWait() {}
+
+        /**
+         * Waits for a condition variable using the supplied mutex as a queue.
+         *
+         * @param lock  mutex to queue on
+         * @return 0 for success, non-zero for failure
+         */
+        virtual int wait(Mutex* lock)=0;
+
+        /**
+         * Waits for a condition variable using the supplied mutex as a queue,
+         * but only for a certain time limit.
+         *
+         * @param lock          mutex to queue on
+         * @param delay_seconds maximum time to wait before waking up
+         * @return 0 for success, non-zero for failure
+         */
+        virtual int timedwait(Mutex* lock, int delay_seconds)=0;
+
+        /**
+         * Signal a single thread to wake up if a condition changes.
+         *
+         * @return 0 for success, non-zero for failure
+         */
+        virtual int signal()=0;
+
+        /**
+         * Signal all threads to wake up if a condition changes.
+         *
+         * @return 0 for success, non-zero for failure
+         */
+        virtual int broadcast()=0;
+
+        /**
+         * Creates a new condition variable.
+         *
+         * @return the new condition variable
+         */
+        static CondWait* create();
+    };
+
+    /**
+     * RAII wrapper for a mutex lock.
+     */
+    class XMLTOOL_API Lock {
+        MAKE_NONCOPYABLE(Lock);
+    public:
+        /**
+         * Locks and wraps the designated mutex.
+         *
+         * @param mtx mutex to lock
+         */
+        Lock(Mutex* mtx) : mutex(mtx) {
+            if (mutex)
+                mutex->lock();
+        }
+
+        /**
+         * Unlocks the wrapped mutex.
+         */
+        ~Lock() {
+            if (mutex)
+                mutex->unlock();
+        }
+
+    private:
+        Mutex* mutex;
+    };
+
+    /**
+     * RAII wrapper for a shared lock.
+     */
+    class XMLTOOL_API SharedLock {
+        MAKE_NONCOPYABLE(SharedLock);
+    public:
+        /**
+         * Locks and wraps the designated shared lock.
+         *
+         * @param lock      lock to acquire
+         * @param lockit    true if the lock should be acquired here, false if already acquired
+         */
+        SharedLock(RWLock* lock, bool lockit=true) : rwlock(lock) {
+            if (rwlock && lockit)
+                rwlock->rdlock();
+        }
+
+        /**
+         * Unlocks the wrapped shared lock.
+         */
+        ~SharedLock() {
+            if (rwlock)
+                rwlock->unlock();
+        }
+
+    private:
+        RWLock* rwlock;
+    };
+
+}
+
+#endif /* _xmltooling_threads_h */