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