wow. that was easy: git mv core nucleus
[feisty_meow.git] / nucleus / library / basis / mutex.cpp
diff --git a/nucleus/library/basis/mutex.cpp b/nucleus/library/basis/mutex.cpp
new file mode 100644 (file)
index 0000000..0bf8b94
--- /dev/null
@@ -0,0 +1,111 @@
+/*****************************************************************************\
+*                                                                             *
+*  Name   : mutex                                                             *
+*  Author : Chris Koeritz                                                     *
+*                                                                             *
+*******************************************************************************
+* Copyright (c) 1996-$now By Author.  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 is online at:      *
+*     http://www.fsf.org/copyleft/gpl.html                                    *
+* Please send any updates to: fred@gruntose.com                               *
+\*****************************************************************************/
+
+// NOTE: we are explicitly avoiding use of new and delete here because this
+//       class is needed by our memory allocation object, which would be
+//       providing the new and delete methods.
+
+#include "mutex.h"
+
+#include <stdlib.h>
+
+#ifdef __UNIX__
+  #include <pthread.h>
+#endif
+#ifdef __WIN32__
+  #define _WINSOCKAPI_  // make windows.h happy about winsock.
+  #include <windows.h>
+#endif
+
+namespace basis {
+
+mutex::mutex() { construct(); }
+
+mutex::~mutex() { destruct(); }
+
+void mutex::establish_lock() { lock(); }
+
+void mutex::repeal_lock() { unlock(); }
+
+void mutex::construct()
+{
+#ifdef __WIN32__
+  c_os_mutex = (CRITICAL_SECTION *)malloc(sizeof(CRITICAL_SECTION));
+  InitializeCriticalSection((LPCRITICAL_SECTION)c_os_mutex);
+#elif defined(__UNIX__)
+  pthread_mutexattr_t attr;
+  pthread_mutexattr_init(&attr);
+  int ret = -1;
+#ifdef __APPLE__
+  ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+#else
+  ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
+#endif
+  if (ret != 0) {
+//printf("failed to initialize mutex attributes!\n"); fflush(NIL);
+  }
+  c_os_mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
+  pthread_mutex_init((pthread_mutex_t *)c_os_mutex, &attr);
+  pthread_mutexattr_destroy(&attr);
+#else
+  #pragma error("no implementation of mutexes for this OS yet!")
+#endif
+}
+
+void mutex::destruct()
+{
+  defang();
+}
+
+void mutex::defang()
+{
+  if (!c_os_mutex) return;  // already defunct.
+#ifdef __WIN32__
+  DeleteCriticalSection((LPCRITICAL_SECTION)c_os_mutex);
+  free(c_os_mutex);
+#elif defined(__UNIX__)
+  pthread_mutex_destroy((pthread_mutex_t *)c_os_mutex);
+  free(c_os_mutex);
+#else
+  #pragma error("no implementation of mutexes for this OS yet!")
+#endif
+  c_os_mutex = 0;
+}
+
+void mutex::lock()
+{
+  if (!c_os_mutex) return;
+#ifdef __WIN32__
+  EnterCriticalSection((LPCRITICAL_SECTION)c_os_mutex);
+#elif defined(__UNIX__)
+  pthread_mutex_lock((pthread_mutex_t *)c_os_mutex);
+#else
+  #pragma error("no implementation of mutexes for this OS yet!")
+#endif
+}
+
+void mutex::unlock()
+{
+  if (!c_os_mutex) return;
+#ifdef __WIN32__
+  LeaveCriticalSection((LPCRITICAL_SECTION)c_os_mutex);
+#elif defined(__UNIX__)
+  pthread_mutex_unlock((pthread_mutex_t *)c_os_mutex);
+#else
+  #pragma error("no implementation of mutexes for this OS yet!")
+#endif
+}
+
+} //namespace.
+