Squashed 'third_party/rawrtc/re/' content from commit f3163ce8b

Change-Id: I6a235e6ac0f03269d951026f9d195da05c40fdab
git-subtree-dir: third_party/rawrtc/re
git-subtree-split: f3163ce8b526a13b35ef71ce4dd6f43585064d8a
diff --git a/src/lock/lock.c b/src/lock/lock.c
new file mode 100644
index 0000000..1f5f2de
--- /dev/null
+++ b/src/lock/lock.c
@@ -0,0 +1,142 @@
+/**
+ * @file lock/lock.c  Pthread mutex locking
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#define _DEFAULT_SOURCE 1
+#define __USE_UNIX98 1
+#include <pthread.h>
+#include <re_types.h>
+#include <re_mem.h>
+#include <re_lock.h>
+
+
+#define DEBUG_MODULE "lock"
+#define DEBUG_LEVEL 5
+#include <re_dbg.h>
+
+
+#ifndef RELEASE
+#define LOCK_DEBUG 0
+#endif
+
+
+/** Defines a lock */
+struct lock {
+	pthread_mutex_t m;
+};
+
+
+static void lock_destructor(void *data)
+{
+	struct lock *l = data;
+
+	int err = pthread_mutex_destroy(&l->m);
+	if (err) {
+		DEBUG_WARNING("pthread_mutex_destroy: %m\n", err);
+	}
+}
+
+
+/**
+ * Allocate a new lock
+ *
+ * @param lp Pointer to allocated lock object
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int lock_alloc(struct lock **lp)
+{
+	pthread_mutexattr_t attr;
+	struct lock *l;
+
+	if (!lp)
+		return EINVAL;
+
+	l = mem_zalloc(sizeof(*l), lock_destructor);
+	if (!l)
+		return ENOMEM;
+
+	(void)pthread_mutex_init(&l->m, NULL);
+
+	pthread_mutexattr_init(&attr);
+
+#if LOCK_DEBUG
+	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
+	DEBUG_NOTICE("init debug lock\n");
+#else
+	pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
+#endif
+	pthread_mutex_init(&l->m, &attr);
+
+	*lp = l;
+	return 0;
+}
+
+
+/**
+ * Get the lock for reading
+ *
+ * @param l Lock object
+ */
+void lock_read_get(struct lock *l)
+{
+	const int err = pthread_mutex_lock(&l->m);
+	if (err) {
+		DEBUG_WARNING("lock_read_get: %m\n", err);
+	}
+}
+
+
+/**
+ * Get the lock for writing
+ *
+ * @param l Lock object
+ */
+void lock_write_get(struct lock *l)
+{
+	const int err = pthread_mutex_lock(&l->m);
+	if (err) {
+		DEBUG_WARNING("lock_write_get: %m\n", err);
+	}
+}
+
+
+/**
+ * Attempt to get a lock for reading
+ *
+ * @param l Lock object
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int lock_read_try(struct lock *l)
+{
+	return pthread_mutex_trylock(&l->m);
+}
+
+
+/**
+ * Attempt to get a lock for writing
+ *
+ * @param l Lock object
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int lock_write_try(struct lock *l)
+{
+	return pthread_mutex_trylock(&l->m);
+}
+
+
+/**
+ * Release a lock
+ *
+ * @param l Lock object
+ */
+void lock_rel(struct lock *l)
+{
+	const int err = pthread_mutex_unlock(&l->m);
+	if (err) {
+		DEBUG_WARNING("lock_rel: %m\n", err);
+	}
+}
diff --git a/src/lock/mod.mk b/src/lock/mod.mk
new file mode 100644
index 0000000..ffe0e55
--- /dev/null
+++ b/src/lock/mod.mk
@@ -0,0 +1,17 @@
+#
+# mod.mk
+#
+# Copyright (C) 2010 Creytiv.com
+#
+
+ifdef HAVE_PTHREAD_RWLOCK
+SRCS	+= lock/rwlock.c
+else
+ifdef HAVE_PTHREAD
+SRCS	+= lock/lock.c
+endif
+endif
+
+ifeq ($(OS),win32)
+SRCS	+= lock/win32/lock.c
+endif
diff --git a/src/lock/rwlock.c b/src/lock/rwlock.c
new file mode 100644
index 0000000..0f6605f
--- /dev/null
+++ b/src/lock/rwlock.c
@@ -0,0 +1,114 @@
+/**
+ * @file rwlock.c  Pthread read/write locking
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#define _GNU_SOURCE 1
+#include <pthread.h>
+#include <re_types.h>
+#include <re_mem.h>
+#include <re_lock.h>
+
+
+#define DEBUG_MODULE "rwlock"
+#define DEBUG_LEVEL 5
+#include <re_dbg.h>
+
+
+struct lock {
+	pthread_rwlock_t lock;
+};
+
+
+static void lock_destructor(void *data)
+{
+	struct lock *l = data;
+
+	int err = pthread_rwlock_destroy(&l->lock);
+	if (err) {
+		DEBUG_WARNING("pthread_rwlock_destroy: %m\n", err);
+	}
+}
+
+
+int lock_alloc(struct lock **lp)
+{
+	struct lock *l;
+	int err;
+
+	if (!lp)
+		return EINVAL;
+
+	l = mem_zalloc(sizeof(*l), lock_destructor);
+	if (!l)
+		return ENOMEM;
+
+	err = pthread_rwlock_init(&l->lock, NULL);
+	if (err)
+		goto out;
+
+	*lp = l;
+
+ out:
+	if (err)
+		mem_deref(l);
+	return err;
+}
+
+
+void lock_read_get(struct lock *l)
+{
+	int err;
+
+	if (!l)
+		return;
+
+	err = pthread_rwlock_rdlock(&l->lock);
+	if (err) {
+		DEBUG_WARNING("lock_read_get: %m\n", err);
+	}
+}
+
+
+void lock_write_get(struct lock *l)
+{
+	int err;
+
+	if (!l)
+		return;
+
+	err = pthread_rwlock_wrlock(&l->lock);
+	if (err) {
+		DEBUG_WARNING("lock_write_get: %m\n", err);
+	}
+}
+
+
+int lock_read_try(struct lock *l)
+{
+	if (!l)
+		return EINVAL;
+	return pthread_rwlock_tryrdlock(&l->lock);
+}
+
+
+int lock_write_try(struct lock *l)
+{
+	if (!l)
+		return EINVAL;
+	return pthread_rwlock_trywrlock(&l->lock);
+}
+
+
+void lock_rel(struct lock *l)
+{
+	int err;
+
+	if (!l)
+		return;
+
+	err = pthread_rwlock_unlock(&l->lock);
+	if (err) {
+		DEBUG_WARNING("lock_rel: %m\n", err);
+	}
+}
diff --git a/src/lock/win32/lock.c b/src/lock/win32/lock.c
new file mode 100644
index 0000000..8fb4362
--- /dev/null
+++ b/src/lock/win32/lock.c
@@ -0,0 +1,72 @@
+/**
+ * @file win32/lock.c  Locking for Windows
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#undef  _WIN32_WINNT
+#define _WIN32_WINNT 0x0400
+#include <windows.h>
+#include <re_types.h>
+#include <re_mem.h>
+#include <re_lock.h>
+
+
+struct lock {
+	CRITICAL_SECTION c;
+};
+
+
+static void lock_destructor(void *data)
+{
+	struct lock *l = data;
+
+	DeleteCriticalSection(&l->c);
+}
+
+
+int lock_alloc(struct lock **lp)
+{
+	struct lock *l;
+
+	if (!lp)
+		return EINVAL;
+
+	l = mem_alloc(sizeof(*l), lock_destructor);
+	if (!l)
+		return ENOMEM;
+
+	InitializeCriticalSection(&l->c);
+
+	*lp = l;
+	return 0;
+}
+
+
+void lock_read_get(struct lock *l)
+{
+	EnterCriticalSection(&l->c);
+}
+
+
+void lock_write_get(struct lock *l)
+{
+	EnterCriticalSection(&l->c);
+}
+
+
+int lock_read_try(struct lock *l)
+{
+	return TryEnterCriticalSection(&l->c) ? 0 : ENODEV;
+}
+
+
+int lock_write_try(struct lock *l)
+{
+	return TryEnterCriticalSection(&l->c) ? 0 : ENODEV;
+}
+
+
+void lock_rel(struct lock *l)
+{
+	LeaveCriticalSection(&l->c);
+}