Coverage Report

Created: 2026-10-17 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hdf5/src/H5TSsemaphore.c
Line
Count
Source
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
 * Copyright by The HDF Group.                                               *
3
 * All rights reserved.                                                      *
4
 *                                                                           *
5
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
6
 * terms governing use, modification, and redistribution, is contained in    *
7
 * the LICENSE file, which can be found at the root of the source code       *
8
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
9
 * If you do not have access to either file, you may request a copy from     *
10
 * help@hdfgroup.org.                                                        *
11
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13
/*
14
 * Purpose: This file contains support for semaphores, equivalent to POSIX
15
 *        semaphore's capabilities.
16
 *
17
 *        Emulated semaphores are based off the Netscape Portable Runtime
18
 *        implementation:
19
 * https://hg.mozilla.org/projects/nspr/file/3e25d69ba6b268f2817e920a69eb2c091efe17e6/pr/src/threads/prsem.c
20
 *
21
 * Note:  Because this threadsafety framework operates outside the library,
22
 *        it does not use the error stack (although it does use error macros
23
 *        that don't push errors on a stack) and only uses the "namecheck only"
24
 *        FUNC_ENTER_* / FUNC_LEAVE_* macros.
25
 */
26
27
/****************/
28
/* Module Setup */
29
/****************/
30
31
#include "H5TSmodule.h" /* This source code file is part of the H5TS module */
32
33
/***********/
34
/* Headers */
35
/***********/
36
#include "H5private.h"  /* Generic Functions                   */
37
#include "H5Eprivate.h" /* Error handling                      */
38
#include "H5TSpkg.h"    /* Threadsafety                        */
39
40
#ifdef H5_HAVE_THREADS
41
42
/****************/
43
/* Local Macros */
44
/****************/
45
46
/******************/
47
/* Local Typedefs */
48
/******************/
49
50
/********************/
51
/* Local Prototypes */
52
/********************/
53
54
/*********************/
55
/* Package Variables */
56
/*********************/
57
58
/*****************************/
59
/* Library Private Variables */
60
/*****************************/
61
62
/*******************/
63
/* Local Variables */
64
/*******************/
65
66
#if defined(_WIN32)
67
/*-------------------------------------------------------------------------
68
 * Function: H5TS_semaphore_init
69
 *
70
 * Purpose:  Initialize a H5TS_semaphore_t (does not allocate it)
71
 *
72
 * Return:   Non-negative on success / Negative on failure
73
 *
74
 *-------------------------------------------------------------------------
75
 */
76
herr_t
77
H5TS_semaphore_init(H5TS_semaphore_t *sem, unsigned initial_count)
78
{
79
    /* Check argument */
80
    if (H5_UNLIKELY(NULL == sem))
81
        return FAIL;
82
83
    if (H5_UNLIKELY(NULL == (*sem = CreateSemaphore(NULL, (LONG)initial_count, LONG_MAX, NULL))))
84
        return FAIL;
85
86
    return SUCCEED;
87
} /* end H5TS_semaphore_init() */
88
89
/*-------------------------------------------------------------------------
90
 * Function: H5TS_semaphore_destroy
91
 *
92
 * Purpose:  Destroy a H5TS_semaphore_t (does not free it)
93
 *
94
 * Return:   Non-negative on success / Negative on failure
95
 *
96
 *-------------------------------------------------------------------------
97
 */
98
herr_t
99
H5TS_semaphore_destroy(H5TS_semaphore_t *sem)
100
{
101
    /* Check argument */
102
    if (H5_UNLIKELY(NULL == sem))
103
        return FAIL;
104
105
    if (H5_UNLIKELY(0 == CloseHandle(*sem)))
106
        return FAIL;
107
108
    return SUCCEED;
109
} /* end H5TS_semaphore_destroy() */
110
111
#elif defined(__unix__) && !defined(__MACH__)
112
/*
113
 * POSIX semaphores
114
 */
115
116
/*-------------------------------------------------------------------------
117
 * Function: H5TS_semaphore_init
118
 *
119
 * Purpose:  Initialize a H5TS_semaphore_t (does not allocate it)
120
 *
121
 * Return:   Non-negative on success / Negative on failure
122
 *
123
 *-------------------------------------------------------------------------
124
 */
125
herr_t
126
H5TS_semaphore_init(H5TS_semaphore_t *sem, unsigned initial_count)
127
0
{
128
    /* Check argument */
129
0
    if (H5_UNLIKELY(NULL == sem))
130
0
        return FAIL;
131
132
0
    if (H5_UNLIKELY(0 != sem_init(sem, 0, initial_count)))
133
0
        return FAIL;
134
135
0
    return SUCCEED;
136
0
} /* end H5TS_semaphore_init() */
137
138
/*-------------------------------------------------------------------------
139
 * Function: H5TS_semaphore_destroy
140
 *
141
 * Purpose:  Destroy a H5TS_semaphore_t (does not free it)
142
 *
143
 * Return:   Non-negative on success / Negative on failure
144
 *
145
 *-------------------------------------------------------------------------
146
 */
147
herr_t
148
H5TS_semaphore_destroy(H5TS_semaphore_t *sem)
149
0
{
150
    /* Check argument */
151
0
    if (H5_UNLIKELY(NULL == sem))
152
0
        return FAIL;
153
154
0
    if (H5_UNLIKELY(0 != sem_destroy(sem)))
155
0
        return FAIL;
156
157
0
    return SUCCEED;
158
0
} /* end H5TS_semaphore_destroy() */
159
#else
160
/*
161
 * Emulate semaphore w/mutex & condition variable
162
 */
163
164
/*-------------------------------------------------------------------------
165
 * Function: H5TS_semaphore_init
166
 *
167
 * Purpose:  Initialize a H5TS_semaphore_t (does not allocate it)
168
 *
169
 * Return:   Non-negative on success / Negative on failure
170
 *
171
 *-------------------------------------------------------------------------
172
 */
173
herr_t
174
H5TS_semaphore_init(H5TS_semaphore_t *sem, unsigned initial_count)
175
{
176
    /* Check argument */
177
    if (H5_UNLIKELY(NULL == sem))
178
        return FAIL;
179
180
    if (H5_UNLIKELY(H5TS_mutex_init(&sem->mutex, H5TS_MUTEX_TYPE_PLAIN) < 0))
181
        return FAIL;
182
    if (H5_UNLIKELY(H5TS_cond_init(&sem->cond) < 0)) {
183
        H5TS_mutex_destroy(&sem->mutex);
184
        return FAIL;
185
    }
186
    sem->waiters = 0;
187
    sem->counter = (int)initial_count;
188
189
    return SUCCEED;
190
} /* end H5TS_semaphore_init() */
191
192
/*-------------------------------------------------------------------------
193
 * Function: H5TS_semaphore_destroy
194
 *
195
 * Purpose:  Destroy a H5TS_semaphore_t (does not free it)
196
 *
197
 * Return:   Non-negative on success / Negative on failure
198
 *
199
 *-------------------------------------------------------------------------
200
 */
201
herr_t
202
H5TS_semaphore_destroy(H5TS_semaphore_t *sem)
203
{
204
    herr_t ret_value = SUCCEED;
205
206
    /* Check argument */
207
    if (H5_UNLIKELY(NULL == sem))
208
        return FAIL;
209
210
    if (H5_UNLIKELY(H5TS_mutex_destroy(&sem->mutex) < 0))
211
        ret_value = FAIL;
212
    if (H5_UNLIKELY(H5TS_cond_destroy(&sem->cond) < 0))
213
        return FAIL;
214
215
    return ret_value;
216
} /* end H5TS_semaphore_destroy() */
217
#endif
218
219
#endif /* H5_HAVE_THREADS */