6a9af775879059f5e4730c69ea3d874f26ccd1e3
[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   #define _WINSOCKAPI_  // make windows.h happy about winsock.
29   #include <windows.h>
30 #endif
31
32 namespace basis {
33
34 mutex::mutex() { construct(); }
35
36 mutex::~mutex() { destruct(); }
37
38 void mutex::establish_lock() { lock(); }
39
40 void mutex::repeal_lock() { unlock(); }
41
42 void mutex::construct()
43 {
44 #ifdef __WIN32__
45   c_os_mutex = (CRITICAL_SECTION *)malloc(sizeof(CRITICAL_SECTION));
46   InitializeCriticalSection((LPCRITICAL_SECTION)c_os_mutex);
47 #elif defined(__UNIX__)
48   pthread_mutexattr_t attr;
49   pthread_mutexattr_init(&attr);
50   int ret = -1;
51 #ifdef __APPLE__
52   ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
53 #else
54   ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
55 #endif
56   if (ret != 0) {
57     printf("failed to initialize mutex attributes!\n"); fflush(NIL);
58   }
59   c_os_mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
60   pthread_mutex_init((pthread_mutex_t *)c_os_mutex, &attr);
61   pthread_mutexattr_destroy(&attr);
62 #else
63   #pragma error("no implementation of mutexes for this OS yet!")
64 #endif
65 }
66
67 void mutex::destruct()
68 {
69   defang();
70 }
71
72 void mutex::defang()
73 {
74   if (!c_os_mutex) return;  // already defunct.
75 #ifdef __WIN32__
76   DeleteCriticalSection((LPCRITICAL_SECTION)c_os_mutex);
77   free(c_os_mutex);
78 #elif defined(__UNIX__)
79   pthread_mutex_destroy((pthread_mutex_t *)c_os_mutex);
80   free(c_os_mutex);
81 #else
82   #pragma error("no implementation of mutexes for this OS yet!")
83 #endif
84   c_os_mutex = 0;
85 }
86
87 void mutex::lock()
88 {
89   if (!c_os_mutex) return;
90 #ifdef __WIN32__
91   EnterCriticalSection((LPCRITICAL_SECTION)c_os_mutex);
92 #elif defined(__UNIX__)
93   pthread_mutex_lock((pthread_mutex_t *)c_os_mutex);
94 #else
95   #pragma error("no implementation of mutexes for this OS yet!")
96 #endif
97 }
98
99 void mutex::unlock()
100 {
101   if (!c_os_mutex) return;
102 #ifdef __WIN32__
103   LeaveCriticalSection((LPCRITICAL_SECTION)c_os_mutex);
104 #elif defined(__UNIX__)
105   pthread_mutex_unlock((pthread_mutex_t *)c_os_mutex);
106 #else
107   #pragma error("no implementation of mutexes for this OS yet!")
108 #endif
109 }
110
111 } //namespace.
112