summaryrefslogtreecommitdiff
path: root/ext/tap-mac/tuntap/src/lock.h
diff options
context:
space:
mode:
Diffstat (limited to 'ext/tap-mac/tuntap/src/lock.h')
-rw-r--r--ext/tap-mac/tuntap/src/lock.h160
1 files changed, 160 insertions, 0 deletions
diff --git a/ext/tap-mac/tuntap/src/lock.h b/ext/tap-mac/tuntap/src/lock.h
new file mode 100644
index 00000000..51d3299a
--- /dev/null
+++ b/ext/tap-mac/tuntap/src/lock.h
@@ -0,0 +1,160 @@
+/*
+ * ip tunnel/ethertap device for MacOSX.
+ *
+ * Locking is not as straightforward for Tiger. So declare our own locking class.
+ */
+/*
+ * Copyright (c) 2011 Mattias Nissler <mattias.nissler@gmx.de>
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are permitted
+ * provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __LOCK_H__
+#define __LOCK_H__
+
+extern "C" {
+
+#include <kern/locks.h>
+#include <sys/param.h>
+
+}
+
+/* our own locking class. declares the common interface of the locking primitives. */
+class tt_lock {
+
+ protected:
+ /* locking group */
+ static lck_grp_t *tt_lck_grp;
+
+ public:
+ /* be virtual */
+ virtual ~tt_lock() { };
+
+ /* static intialization (inits the locking group) */
+ static bool initialize();
+ static void shutdown();
+
+ /* locking */
+ virtual void lock() = 0;
+ virtual void unlock() = 0;
+
+ /* monitor primitives */
+ virtual void sleep(void* cond) = 0;
+ virtual void sleep(void* cond, uint64_t) = 0;
+ virtual void wakeup(void* cond) = 0;
+};
+
+/* simple mutex */
+class tt_mutex : public tt_lock {
+
+ private:
+ /* underlying darwin lock */
+ lck_rw_t *lck;
+
+ public:
+ tt_mutex();
+ virtual ~tt_mutex();
+
+ void lock();
+ void unlock();
+
+ /* monitor primitives */
+ void sleep(void* cond);
+ void sleep(void* cond, uint64_t);
+ void wakeup(void* cond);
+};
+
+/* A very special locking class that we use to track threads that enter and leave the character
+ * device service functions. They call enter() before entering the actual service routinge and
+ * exit() when done. enter() only permits them to pass when the gate isn't locked. Furthermore, the
+ * gate assigns ticket numbers to everyone that passes the gate, so you can check whether more
+ * threads came through. See tuntap_mgr::shutdown() for how we use that stuff.
+ */
+class tt_gate : public tt_lock {
+
+ private:
+ /* synchronization lock */
+ tt_mutex slock;
+ /* ticket number */
+ unsigned int ticket_number;
+ /* count of threads that are in */
+ unsigned int population;
+
+ public:
+ /* construct a new gate */
+ tt_gate();
+
+ /* enter - pass the gate */
+ void enter();
+ /* exit - pass the gate */
+ void exit();
+
+ /* check whether anyone is in */
+ bool is_anyone_in();
+ /* gets the next ticket number */
+ unsigned int get_ticket_number();
+
+ /* lock the gate */
+ void lock();
+ /* unlock the gate */
+ void unlock();
+
+ /* monitor primitives */
+ void sleep(void* cond);
+ void sleep(void* cond, uint64_t);
+ void wakeup(void* cond);
+};
+
+/* auto_lock and auto_rwlock serve as automatic lock managers: Create an object, passing the
+ * tt_[rw]lock you want to lock to have it grab the lock. When the object goes out of scope, the
+ * destructor of the class will release the lock.
+ */
+class auto_lock {
+
+ protected:
+ /* the lock we hold */
+ tt_lock *l;
+
+ public:
+ auto_lock(tt_lock *m)
+ : l(m)
+ {
+ lock();
+ }
+
+ ~auto_lock()
+ {
+ unlock();
+ }
+
+ void lock()
+ {
+ l->lock();
+ }
+
+ void unlock()
+ {
+ l->unlock();
+ }
+};
+
+#endif /* __LOCK_H__ */
+