This is Unofficial EPICS BASE Doxygen Site
osdMutex.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2002 The University of Chicago, as Operator of Argonne
3 * National Laboratory.
4 * Copyright (c) 2002 The Regents of the University of California, as
5 * Operator of Los Alamos National Laboratory.
6 * EPICS BASE Versions 3.13.7
7 * and higher are distributed subject to a Software License Agreement found
8 * in file LICENSE that is included with this distribution.
9 \*************************************************************************/
10 /* osdMutex.c */
11 /*
12  * WIN32 version
13  *
14  * Author Jeffrey O. Hill
15  * johill@lanl.gov
16  * 505 665 1831
17  *
18  */
19 
20 #include <stdio.h>
21 #include <limits.h>
22 
23 #define VC_EXTRALEAN
24 #define STRICT
25 /*
26  * Defining this allows the *much* faster critical
27  * section mutex primitive to be used. Unfortunately,
28  * using certain of these functions drops support for W95\W98\WME
29  * unless we specify "delay loading" when we link with the
30  * DLL so that DLL entry points are not resolved until they
31  * are used. The code does have run time switches so
32  * that the more advanced calls are not called unless
33  * they are available in the windows OS, but this feature
34  * isnt going to be very useful unless we specify "delay
35  * loading" when we link with the DLL.
36  *
37  * It appears that the only entry point used here that causes
38  * portability problems with W95\W98\WME is TryEnterCriticalSection.
39  */
40 #ifndef _WIN32_WINNT
41 # define _WIN32_WINNT 0x0400
42 #endif
43 #include <windows.h>
44 
45 #include "libComAPI.h"
46 #include "epicsMutex.h"
47 #include "epicsAssert.h"
48 #include "epicsStdio.h"
49 
50 typedef struct epicsMutexOSD {
51  union {
52  HANDLE mutex;
53  CRITICAL_SECTION criticalSection;
54  } os;
56 
57 static BOOL thisIsNT = FALSE;
58 static LONG weHaveInitialized = 0;
59 
60 /*
61  * epicsMutexCreate ()
62  */
64 {
65  epicsMutexOSD * pSem;
66 
67  if ( ! weHaveInitialized ) {
68  BOOL status;
69  OSVERSIONINFO osInfo;
70  osInfo.dwOSVersionInfoSize = sizeof ( OSVERSIONINFO );
71  status = GetVersionEx ( & osInfo );
72  thisIsNT = status && ( osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT );
73  weHaveInitialized = 1;
74  }
75 
76  pSem = malloc ( sizeof (*pSem) );
77  if ( pSem ) {
78  if ( thisIsNT ) {
79  InitializeCriticalSection ( &pSem->os.criticalSection );
80  }
81  else {
82  pSem->os.mutex = CreateMutex ( NULL, FALSE, NULL );
83  if ( pSem->os.mutex == 0 ) {
84  free ( pSem );
85  pSem = 0;
86  }
87  }
88  }
89  return pSem;
90 }
91 
92 /*
93  * epicsMutexOsdDestroy ()
94  */
96 {
97  if ( thisIsNT ) {
98  DeleteCriticalSection ( &pSem->os.criticalSection );
99  }
100  else {
101  CloseHandle ( pSem->os.mutex );
102  }
103  free ( pSem );
104 }
105 
106 /*
107  * epicsMutexOsdUnlock ()
108  */
110 {
111  if ( thisIsNT ) {
112  LeaveCriticalSection ( &pSem->os.criticalSection );
113  }
114  else {
115  BOOL success = ReleaseMutex ( pSem->os.mutex );
116  assert ( success );
117  }
118 }
119 
120 /*
121  * epicsMutexOsdLock ()
122  */
124 {
125  if ( thisIsNT ) {
126  EnterCriticalSection ( &pSem->os.criticalSection );
127  }
128  else {
129  DWORD status = WaitForSingleObject ( pSem->os.mutex, INFINITE );
130  if ( status != WAIT_OBJECT_0 ) {
131  return epicsMutexLockError;
132  }
133  }
134  return epicsMutexLockOK;
135 }
136 
137 /*
138  * epicsMutexOsdTryLock ()
139  */
141 {
142  if ( thisIsNT ) {
143  if ( TryEnterCriticalSection ( &pSem->os.criticalSection ) ) {
144  return epicsMutexLockOK;
145  }
146  else {
147  return epicsMutexLockTimeout;
148  }
149  }
150  else {
151  DWORD status = WaitForSingleObject ( pSem->os.mutex, 0 );
152  if ( status != WAIT_OBJECT_0 ) {
153  if (status == WAIT_TIMEOUT) {
154  return epicsMutexLockTimeout;
155  }
156  else {
157  return epicsMutexLockError;
158  }
159  }
160  }
161  return epicsMutexLockOK;
162 }
163 
164 /*
165  * epicsMutexOsdShow ()
166  */
167 void epicsMutexOsdShow ( epicsMutexOSD * pSem, unsigned level )
168 {
169  if ( thisIsNT ) {
170  printf ("epicsMutex: win32 critical section at %p\n",
171  (void * ) & pSem->os.criticalSection );
172  }
173  else {
174  printf ( "epicsMutex: win32 mutex at %p\n",
175  ( void * ) pSem->os.mutex );
176  }
177 }
178 
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
#define FALSE
Definition: dbDefs.h:32
HANDLE mutex
Definition: osdMutex.c:52
pvd::Status status
An EPICS-specific replacement for ANSI C&#39;s assert.
#define printf
Definition: epicsStdio.h:41
#define NULL
Definition: catime.c:38
void epicsMutexOsdUnlock(struct epicsMutexOSD *pmutex)
Definition: osdMutex.c:237
struct epicsMutexOSD epicsMutexOSD
union epicsMutexOSD::@18 os
epicsMutexLockStatus epicsMutexOsdLock(struct epicsMutexOSD *pmutex)
Definition: osdMutex.c:276
epicsMutexOSD * epicsMutexOsdCreate(void)
Definition: osdMutex.c:175
APIs for the epicsMutex mutual exclusion semaphore.
epicsMutexLockStatus epicsMutexOsdTryLock(struct epicsMutexOSD *pmutex)
Definition: osdMutex.c:301
epicsMutexLockStatus
Definition: epicsMutex.h:51
void epicsMutexOsdDestroy(struct epicsMutexOSD *pmutex)
Definition: osdMutex.c:221
CRITICAL_SECTION criticalSection
Definition: osdMutex.c:53
void epicsMutexOsdShow(struct epicsMutexOSD *pmutex, unsigned int level)
Definition: osdMutex.c:329