updates from orpheus for windoze build
[feisty_meow.git] / nucleus / library / basis / mutex.cpp
1 /*****************************************************************************\
2 *                                                                             *
3 *  Name   : mutex                                                             *
4 *  Author : Chris Koeritz                                                     *
5 *                                                                             *
6 *******************************************************************************
7 * Copyright (c) 1996-$now By Author.  This program is free software; you can  *
8 * redistribute it and/or modify it under the terms of the GNU General Public  *
9 * License as published by the Free Software Foundation; either version 2 of   *
10 * the License or (at your option) any later version.  This is online at:      *
11 *     http://www.fsf.org/copyleft/gpl.html                                    *
12 * Please send any updates to: fred@gruntose.com                               *
13 \*****************************************************************************/
14
15 // NOTE: we are explicitly avoiding use of new and delete here because this
16 //       class is needed by our memory allocation object, which would be
17 //       providing the new and delete methods.
18
19 #include "mutex.h"
20
21 #include <stdio.h>
22 #include <stdlib.h>
23
24 #ifdef __UNIX__
25   #include <pthread.h>
26 #endif
27 #ifdef __WIN32__
28   #include <synchapi.h>
29 /*
30   #define _WINSOCKAPI_  // make windows.h happy about winsock.
31   // winsock support...
32 //  #undef FD_SETSIZE
33 //  #define FD_SETSIZE 1000
34     // if you don't set this, you can only select on a default of 64 sockets.
35   #include <winsock2.h>
36   #include <windows.h>
37   */
38 #endif
39
40 namespace basis {
41
42 mutex::mutex() { construct(); }
43
44 mutex::~mutex() { destruct(); }
45
46 void mutex::establish_lock() { lock(); }
47
48 void mutex::repeal_lock() { unlock(); }
49
50 void mutex::construct()
51 {
52 #ifdef __WIN32__
53   c_os_mutex = (CRITICAL_SECTION *)malloc(sizeof(CRITICAL_SECTION));
54   InitializeCriticalSection((LPCRITICAL_SECTION)c_os_mutex);
55 #elif defined(__UNIX__)
56   pthread_mutexattr_t attr;
57   pthread_mutexattr_init(&attr);
58   int ret = -1;
59 #ifdef __APPLE__
60   ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
61 #else
62   ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
63 #endif
64   if (ret != 0) {
65     printf("failed to initialize mutex attributes!\n"); fflush(NULL_POINTER);
66   }
67   c_os_mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
68   pthread_mutex_init((pthread_mutex_t *)c_os_mutex, &attr);
69   pthread_mutexattr_destroy(&attr);
70 #else
71   #pragma error("no implementation of mutexes for this OS yet!")
72 #endif
73 }
74
75 void mutex::destruct()
76 {
77   defang();
78 }
79
80 void mutex::defang()
81 {
82   if (!c_os_mutex) return;  // already defunct.
83 #ifdef __WIN32__
84   DeleteCriticalSection((LPCRITICAL_SECTION)c_os_mutex);
85   free(c_os_mutex);
86 #elif defined(__UNIX__)
87   pthread_mutex_destroy((pthread_mutex_t *)c_os_mutex);
88   free(c_os_mutex);
89 #else
90   #pragma error("no implementation of mutexes for this OS yet!")
91 #endif
92   c_os_mutex = 0;
93 }
94
95 void mutex::lock()
96 {
97   if (!c_os_mutex) return;
98 #ifdef __WIN32__
99   EnterCriticalSection((LPCRITICAL_SECTION)c_os_mutex);
100 #elif defined(__UNIX__)
101   pthread_mutex_lock((pthread_mutex_t *)c_os_mutex);
102 #else
103   #pragma error("no implementation of mutexes for this OS yet!")
104 #endif
105 }
106
107 void mutex::unlock()
108 {
109   if (!c_os_mutex) return;
110 #ifdef __WIN32__
111   LeaveCriticalSection((LPCRITICAL_SECTION)c_os_mutex);
112 #elif defined(__UNIX__)
113   pthread_mutex_unlock((pthread_mutex_t *)c_os_mutex);
114 #else
115   #pragma error("no implementation of mutexes for this OS yet!")
116 #endif
117 }
118
119 } //namespace.
120