2 * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <vehicle_service/positioning_base_library.h>
23 #include "_pbInternalProc.h"
24 #include "WPF_STD_private.h"
28 Constants and structure definitions
29 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
30 #define MAX_PB_SEMAPHORES 256
31 #define MAX_SEMAPHORE_NAME_LEN 32
32 #define MAX_PB_SEMAPHORES_INPROC 16
34 /* Name storage table */
36 TCHAR semaphore_name[MAX_SEMAPHORE_NAME_LEN + 1]; /* Semaphore name(Specified name of the user APP) */
37 DWORD ref_counter; /* Reference Counter (Currently unused, always 1) */
40 /* Control information storage table */
42 HANDLE h_heap; /* Handle of the heap area allocated for expanding the self TBL (control-information-storage TBL) */
43 PB_SEMAPHORE* p_sys_semaphore; /* Address where the self name in the name storage table is stored (Top address of self name) */
44 DWORD index; /* Semaphore ID that is equal to the index of self TBL (control information strage TBL:p_handle_table) + 1 */
45 HANDLE h_semaphore; /* Semaphore handle (Semaphore or Mutex according to the above DEBUG defines) */
46 HANDLE h_mutex; /* Mutex handle for locking when updating the self TBL (control information storage TBL) */
47 } PB_SEMAPHORE_OPEN_HANDLE;
49 /* Semaphore information management table */
51 PB_SEMAPHORE_OPEN_HANDLE* p_handle_table[MAX_PB_SEMAPHORES]; /* Pointer to control information storage table */
52 HANDLE h_shared_memory; /* Handle of shared memory allocated for name storage table to expand */
53 HANDLE h_mutex; /* Mutex handle to lock when updating the name storage table */
54 PB_SEMAPHORE* p_semaphore_table; /* Pointer to the name storage table (Allocate as many areas as the maximum number of registrations in shared memory)*/
55 } PB_SEMAPHORE_INSTANCE;
57 typedef struct /* In-process semaphore management table */ {
58 char semaphore_name[MAX_SEMAPHORE_NAME_LEN]; /* Semaphore name (Specified name of the user APP) */
59 HANDLE h_heap; /* Heap handle of critical section structure area */
60 CRITICAL_SECTION *p_cs; /* Critical section pointer(Semaphore ID) */
64 Internal function prototype declarations
65 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
66 static DWORD FindSemaphoreTable(PB_SEMAPHORE* p_semaphore_table, TCHAR* name, HANDLE h_mutex);
67 static DWORD AllocNewSemaphoreTable(PB_SEMAPHORE* p_semaphore_table, TCHAR* name, HANDLE h_mutex);
68 static void FreeSemaphoreTable(PB_SEMAPHORE* p_semaphore_table, int index, HANDLE h_mutex);
71 Global variable definitions
72 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
73 static PB_SEMAPHORE_INSTANCE g_instance; // NOLINT(readability/nolint) global class instance
74 /* CS for exclusive control of in-process semaphore management table */
75 CRITICAL_SECTION g_sem_in_proc_tbl_mng_cs;
76 /* Pointer to the in-process semaphore management table */
77 PB_SEM_INPROC *g_p_sem_in_proc_mng = NULL;
83 MakeSemaphoreName(TCHAR* name, DWORD index) {
84 wsprintf(name, __TEXT("POS_BASE_SEMAPHORE_SEM%05d"), static_cast<int32>(index));
87 MakeMutexName(TCHAR* name, DWORD index) {
88 wsprintf(name, __TEXT("POS_BASE_SEMAPHORE_MUTEX%05d"), static_cast<int32>(index));
91 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
92 * MODULE : SemaphoreInit
93 * ABSTRACT : Semaphore initialization processing
94 * NOTE : This function is called when _CWORD64_api.dll is ATTACH from processes
95 * : and initializes the process.
97 * RETURN : RET_API RET_NORMAL Normal completion
99 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
101 SemaphoreInit(void) {
102 RET_API ret_api = RET_NORMAL;
103 PB_SEMAPHORE_INSTANCE *p_inst = &g_instance;
104 TCHAR name[32] = {0};
105 DWORD semaphore_table_size = 0;
107 PB_SEMAPHORE *p_semaphore_table = NULL;
108 BOOL b_create = FALSE;
110 /* Initialize the semaphore information management table */
111 for (n = 0; n < MAX_PB_SEMAPHORES; n++) {
112 p_inst->p_handle_table[n] = NULL; /* NULL initialize the control data storage table */
115 /* Initialize the semaphore name storage table */
116 _tcscpy(name, __TEXT("POS_BASE_SEMAPHORE_TABLE"));
117 semaphore_table_size = sizeof(PB_SEMAPHORE) * MAX_PB_SEMAPHORES;
118 /* Open shared memory with the name _CWORD64__SEMAPHORE_TABLE */
119 p_inst->h_shared_memory = OpenSharedMemory(name, semaphore_table_size);
120 if (p_inst->h_shared_memory == NULL) /* If shared memory does not exist */ {
121 /* Create a shared memory with the name _CWORD64__SEMAPHORE_TABLE */
122 p_inst->h_shared_memory = CreateSharedMemory(name, semaphore_table_size);
123 if (p_inst->h_shared_memory == NULL) /* If shared memory creation fails */ {
124 ret_api = RET_ERRINIT; /* Ends in error */
126 b_create = TRUE; /* Create shared memory */
128 /* Allocate the created shared memory to the semaphore name storage table and initialize it. */
129 // LCOV_EXCL_BR_START 200: cannot be null
130 p_semaphore_table = reinterpret_cast<PB_SEMAPHORE*>(GetSharedMemoryPtr(p_inst->h_shared_memory));
132 if (p_semaphore_table == NULL) { // LCOV_EXCL_BR_LINE 200: cannot be null
133 // LCOV_EXCL_START 200: cannot be null
134 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
135 CloseSharedMemory(p_inst->h_shared_memory);
136 DeleteSharedMemory(name);
137 ret_api = RET_ERRINIT; /* Ends in error */
140 for (n = 0; n < MAX_PB_SEMAPHORES; n++) {
141 p_semaphore_table[n].semaphore_name[0] = __TEXT('\0'); /* Initialize name */
142 p_semaphore_table[n].ref_counter = 0; /* Initialize reference counter */
148 if (ret_api == RET_NORMAL) {
149 /* Save the address of the shared memory to the name storage table pointer of the semaphore information management table. */
150 // LCOV_EXCL_BR_START 200: cannot be null
151 p_inst->p_semaphore_table = reinterpret_cast<PB_SEMAPHORE*>(GetSharedMemoryPtr(p_inst->h_shared_memory));
153 if (p_inst->p_semaphore_table == NULL) { // LCOV_EXCL_BR_LINE 200: cannot be null
154 // LCOV_EXCL_START 200: cannot be null
155 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
156 CloseSharedMemory(p_inst->h_shared_memory);
157 if (b_create != FALSE) {
158 DeleteSharedMemory(name);
160 ret_api = RET_ERRINIT; /* Ends in error */
163 /* Mutex creation process for semaphore-information-management table */
164 _tcscpy(name, __TEXT("POS_BASE_SEMAPHORE_MUTEX"));
165 /* Save the handle of the created Mutex in the Mutex handles for semaphore-information-management-table */
166 p_inst->h_mutex = _pb_CreateMutex(NULL, FALSE, name); // LCOV_EXCL_BR_LINE 200: can not be null
167 if (p_inst->h_mutex == NULL) { /* Failed to create a Mutex. */ // LCOV_EXCL_BR_LINE 200: can not be null
168 // LCOV_EXCL_START 200: can not be null
169 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
170 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "_CWORD64_api.dll:%s:LINE %d\r\n CreateMutex ERROR " \
171 "In SemaphoreInit\r\n", LTEXT(__FILE__), __LINE__);
172 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Mutex_Name : %s\r\n", name);
182 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
183 * MODULE : SemaphoreTerm
184 * ABSTRACT : Semaphore function termination processing
185 * NOTE : Called when the process ATTACH to _CWORD64_api.dll terminates, and then terminated.
187 * RETURN : RET_API RET_NORMAL Always this value
188 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
190 SemaphoreTerm(void) { // LCOV_EXCL_START 8:dead code
191 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
192 PB_SEMAPHORE_INSTANCE *p_inst = &g_instance;
194 if (p_inst->h_mutex != NULL) {
195 PbDeleteMutex(p_inst->h_mutex);
196 p_inst->h_mutex = NULL;
199 if (p_inst->h_shared_memory != NULL) {
200 CloseSharedMemory(p_inst->h_shared_memory);
201 p_inst->h_shared_memory = NULL;
212 * Create a semaphore and return a semaphore ID.<br>
213 * For a semaphore that has already been created, return the same value of the semaphore ID when it has been created.
215 * @param[in] *sem_name Pointer to the semaphore name string to be created (NULL termination)
217 * @return Semaphore ID created other than 0<br>
218 * 0 ABEND to create semaphore
220 #ifdef _CWORD64_API_DOES_NOT_USE_UNICODE
221 SemID _pb_CreateSemaphore(char* sem_name) // NOLINT(readability/nolint) WPF_SYSAPI.h API
223 SemID _pb_CreateSemaphore(TCHAR* sem_name) // NOLINT(readability/nolint) WPF_SYSAPI.h API
224 #endif // _CWORD64_API_DOES_NOT_USE_UNICODE
226 SemID ret_sem_id = 0;
227 TCHAR *p_semaphore_name = NULL;
228 PB_SEMAPHORE_INSTANCE *p_inst = &g_instance;
229 TCHAR name[MAX_SEMAPHORE_NAME_LEN + 1] = {0};
230 PB_SEMAPHORE_OPEN_HANDLE *p_semaphore_open = NULL;
233 /* Check if the semaphore name is NULL */
234 if (sem_name == NULL) {
236 p_semaphore_name = sem_name;
238 /* Check if the semaphore name is specified */
239 if (p_semaphore_name[0] == __TEXT('\0')) {
240 } else if (_tcslen(p_semaphore_name) > MAX_SEMAPHORE_NAME_LEN) {
241 /* Check whether the semaphore name is less than or equal to the maximum number of characters */
243 /* Allocate Heap control information storage table area to create a semaphore */
244 p_semaphore_open = reinterpret_cast<PB_SEMAPHORE_OPEN_HANDLE *>(PbProcessHeapAlloc(0, \
245 sizeof(PB_SEMAPHORE_OPEN_HANDLE))); // LCOV_EXCL_BR_LINE 200: no branch
248 if (p_semaphore_open != NULL) {
249 PbMutexLock(p_inst->h_mutex, INFINITE); /* Mutex Lock from here */ // LCOV_EXCL_BR_LINE 200: no branch // NOLINT(whitespace/line_length)
251 /* Retrieve the name storage table expanded in the shared memory with the user-specified name. */
252 index = FindSemaphoreTable(p_inst->p_semaphore_table, p_semaphore_name, p_inst->h_mutex);
253 if (index != ((DWORD) - 1)) {
254 /* The semaphore name specified for the user already exists. */
255 /* Check if the control information storage table exists */
256 if (p_inst->p_handle_table[index] != NULL) {
257 /* If the control information storage TBL exists,(If it has already been created by this process) */
258 /* release the previously allocated Heap because it is not needed. */
259 PbProcessHeapFree(0, p_semaphore_open); // LCOV_EXCL_BR_LINE 200: no branch
260 /* Retrieve the pointer to the TBL storing the existing control information. */
261 p_semaphore_open = p_inst->p_handle_table[index];
262 PbMutexUnlock(p_inst->h_mutex); /* Mutex release */ // LCOV_EXCL_BR_LINE 200: no branch
263 /* Convert from an index of array to a semaphore ID and return (If it has already been created in this process) */
264 ret_sem_id = static_cast<SemID>(index + 1);
266 // LCOV_EXCL_START 200: p_handle_table can not be NULL
267 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
268 /* If a semaphore with the established name exists but the control information table does not exist, link to it or create it in the following processing. */
269 /* (A semaphore was created by another process or the created process was terminated.) */
270 /* Store the assigned semaphore ID in the control information storage table. */
271 p_semaphore_open->index = index;
272 /* Store the start address of the name storage table */
273 p_semaphore_open->p_sys_semaphore = &p_inst->p_semaphore_table[index];
274 /* Store the address of the control information TBL (Heap) into the semaphore information management TBL. */
275 p_inst->p_handle_table[index] = p_semaphore_open;
277 /* Create the object name of the semaphore from the position (index of array) of the control information storage TBL. */
278 /* "_CWORD64__SEMAPHORE_SEMAPHORExxxxx" : xxxxx is expanded with five-digit array index */
279 MakeSemaphoreName(name, index);
281 /* Create a semaphore object using Mutex and store its handle into the control information storage TBL. */
282 p_semaphore_open->h_semaphore = _pb_CreateMutex(NULL, FALSE, name);
283 if (p_semaphore_open->h_semaphore == NULL) {
284 /* If the semaphore object creation failed, */
285 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "_CWORD64_api.dll:%s:LINE %d\r\n CreateMutex ERROR " \
286 "In _pb_CreateSemaphore\r\n", LTEXT(__FILE__), __LINE__);
287 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Mutex_Name : %s\r\n", name);
288 _pb_Exit(); /* Make reset */
291 /* Create a Mutex name for locking the control information storage TBL from the position (index of array) of the control information storage TBL */
292 /* "_CWORD64__SEMAPHORE_MUTEXxxxxx" : xxxxx is expanded with five-digit array index */
293 MakeMutexName(name, index);
294 /* Create a Mutex for locking the control information storage TBL and store its handle into the control information storage TBL */
295 p_semaphore_open->h_mutex = _pb_CreateMutex(NULL, FALSE, name);
296 if (p_semaphore_open->h_mutex == NULL) {
297 /* If the creation of a Mutex for locking the control data storage TBL fails, */
298 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "_CWORD64_api.dll:%s:LINE %d\r\n CreateMutex ERROR " \
299 "In _pb_CreateSemaphore\r\n", LTEXT(__FILE__), __LINE__);
300 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Mutex_Name : %s\r\n", name);
303 /* Semaphore Lock for updating semaphore information control TBL */
304 PbMutexLock(p_semaphore_open->h_mutex, INFINITE);
305 p_semaphore_open->p_sys_semaphore->ref_counter = 1;
306 /* Semaphore UnLock upon completion of updating semaphore-information-management-TBL */
307 PbMutexUnlock(p_semaphore_open->h_mutex);
308 /* Semaphore UnLock upon completion of updating semaphore-information-management-TBL */
309 PbMutexUnlock(p_inst->h_mutex);
311 ret_sem_id = static_cast<SemID>(index + 1); /* Convert from an index of array to a semaphore ID and return */
312 /* (A semaphore was created by another process or the created process was terminated.) */
316 /* If the semaphore name specified by the user does not exist, it is newly created in the following processing. */
317 /* Free-space retrieval processing for the name storage table */
318 index = AllocNewSemaphoreTable(p_inst->p_semaphore_table, p_semaphore_name, p_inst->h_mutex);
319 if (index == ((DWORD) - 1)) { // LCOV_EXCL_BR_LINE 200: table buffer is enough, can not failed
320 /* If there is no free space in the name storage table */
321 /* Initialize the name storage TBL pointer of the control information storage TBL. (it may be No meaning due to release heap area in the following processing?) */
322 // LCOV_EXCL_START 200: table buffer is enough, can not failed
323 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
324 p_semaphore_open->p_sys_semaphore = NULL;
325 /* Free the Heap area allocated for control information storage TBL */
326 PbProcessHeapFree(0, p_semaphore_open);
327 /* Semaphore UnLock to recover from errors */
328 PbMutexUnlock(p_inst->h_mutex);
331 /* Store the assigned semaphore ID in the control information storage table. */
332 p_semaphore_open->index = index;
333 /* Store this start address of the name storage table */
334 p_semaphore_open->p_sys_semaphore = &p_inst->p_semaphore_table[index];
335 p_semaphore_open->p_sys_semaphore->ref_counter = 1; /* Reset reference counter. */
336 /* Store the control information TBL (Heap) address in the semaphore information management TBL. */
337 p_inst->p_handle_table[index] = p_semaphore_open;
339 /* Create the object name of the semaphore from the position (array index) of the control information storage TBL. */
340 /* "_CWORD64__SEMAPHORE_SEMAPHORExxxxx" : xxxxx is expanded with five-digit array index */
341 MakeSemaphoreName(name, index);
342 p_semaphore_open->h_semaphore = _pb_CreateMutex(NULL, FALSE, name); // LCOV_EXCL_BR_LINE 200: cannot be null // NOLINT(whitespace/line_length)
343 if (p_semaphore_open->h_semaphore == NULL) { // LCOV_EXCL_BR_LINE 200: cannot be null
344 // LCOV_EXCL_START 200: can not be null
345 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
346 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "_CWORD64_api.dll:%s:LINE %d\r\n CreateMutex ERROR " \
347 "In _pb_CreateSemaphore\r\n", LTEXT(__FILE__), __LINE__);
348 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Mutex_Name : %s\r\n", name);
353 MakeMutexName(name, index);
354 p_semaphore_open->h_mutex = _pb_CreateMutex(NULL, FALSE, name); // LCOV_EXCL_BR_LINE 200: cannot be null // NOLINT(whitespace/line_length)
355 if (p_semaphore_open->h_mutex == NULL) { // LCOV_EXCL_BR_LINE 200: cannot be null
356 // LCOV_EXCL_START 200: can not be null
357 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
358 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "_CWORD64_api.dll:%s:LINE %d\r\n CreateMutex ERROR " \
359 "In _pb_CreateSemaphore\r\n", LTEXT(__FILE__), __LINE__);
360 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " Mutex_Name : %s\r\n", name);
364 /* Semaphore name registration */
365 _tcscpy(p_semaphore_open->p_sys_semaphore->semaphore_name, p_semaphore_name);
367 PbMutexUnlock(p_inst->h_mutex); /* Mutex lock to new create semaphore ends here */ // LCOV_EXCL_BR_LINE 200: no branch // NOLINT(whitespace/line_length)
369 ret_sem_id = static_cast<SemID>(index + 1); /* Convert from an array index to a semaphore ID and return */
375 return ret_sem_id; /* Return the allocated semaphore ID. */
378 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
379 * MODULE : PbDeleteSemaphore
380 * ABSTRACT : Semaphore deletion processing
381 * NOTE : Delete the semaphore specified by semaphore ID
382 * ARGUMENT : SemID sem_id Semaphore ID to be deleted
383 * RETURN : RET_API RET_NORMAL Normal completion
384 * : RET_OSERROR ABEND
385 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
387 PbDeleteSemaphore(SemID sem_id) { // LCOV_EXCL_START 8:dead code
388 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
389 RET_API ret_api = RET_NORMAL;
391 PB_SEMAPHORE_INSTANCE *p_inst = &g_instance;
392 PB_SEMAPHORE_OPEN_HANDLE *p_semaphore_open = NULL;
393 DWORD dw_ret_sts = 0;
394 DWORD ref_counter = 0;
396 /* Parameter check */
398 /* Error if specified semaphore ID is zero */
399 ret_api = RET_OSERROR;
402 if (ret_api == RET_NORMAL) {
403 index = static_cast<int>(sem_id) - 1; /* Calculate the index number of the semaphore table from the specified semaphore ID. */
404 if (index >= MAX_PB_SEMAPHORES) {
405 /* If the specified semaphore ID is out of range */
406 ret_api = RET_OSERROR;
410 if (ret_api == RET_NORMAL) {
411 PbMutexLock(p_inst->h_mutex, INFINITE); /* Need this exclusion? Seems to not be used exclusion at Locking/Unlocking... */
412 p_semaphore_open = p_inst->p_handle_table[index];
413 PbMutexUnlock(p_inst->h_mutex); /* Need this exclusion? Seems to not be used exclusion at Locking/Unlocking... */
414 if (p_semaphore_open == NULL) /* If the specified semaphore ID is not registered in the table */ {
415 ret_api = RET_OSERROR;
419 if (ret_api == RET_NORMAL) {
420 /* Return an error if the semaphore is locked */
421 dw_ret_sts = PbMutexLock(p_semaphore_open->h_semaphore, 0);
422 if (dw_ret_sts == WAIT_TIMEOUT) {
423 ret_api = RET_OSERROR;
427 if (ret_api == RET_NORMAL) {
428 PbMutexUnlock(p_semaphore_open->h_semaphore);
430 PbMutexLock(p_semaphore_open->h_mutex, INFINITE);
431 if (p_semaphore_open->p_sys_semaphore->ref_counter > 0) {
432 p_semaphore_open->p_sys_semaphore->ref_counter--;
435 ref_counter = p_semaphore_open->p_sys_semaphore->ref_counter;
436 PbMutexUnlock(p_semaphore_open->h_mutex);
438 if (ref_counter == 0) {
439 PbMutexLock(p_inst->h_mutex, INFINITE); /* Get Mutex */
441 FreeSemaphoreTable(p_inst->p_semaphore_table, index, p_inst->h_mutex);
442 p_semaphore_open->p_sys_semaphore = NULL;
443 if (p_semaphore_open->h_semaphore != NULL) {
444 PbDeleteMutex(p_semaphore_open->h_semaphore);
445 p_semaphore_open->h_semaphore = NULL;
448 if (p_semaphore_open->h_mutex != NULL) {
449 PbDeleteMutex(p_semaphore_open->h_mutex);
450 p_semaphore_open->h_mutex = NULL;
453 PbProcessHeapFree(0, p_semaphore_open);
455 p_inst->p_handle_table[index] = NULL;
456 PbMutexUnlock(p_inst->h_mutex); /* Release Mutex */
468 * Get the semaphore with the specified semaphore ID. Do not return from this function until it is acquired.
470 * @param[in] sem_id Semaphore ID of the semaphore to be acquired
472 * @return RET_NORMAL Normal completion<br>
475 RET_API _pb_SemLock(SemID sem_id) { // NOLINT(readability/nolint) WPF_SYSAPI.h API
476 RET_API ret_api = RET_OSERROR;
477 PB_SEMAPHORE_INSTANCE *p_inst = &g_instance;
478 PB_SEMAPHORE_OPEN_HANDLE *p_semaphore_open = NULL;
482 /* Parameter check */
484 /* The specified semaphore ID is non-zero */
485 index = static_cast<int>(sem_id) - 1; /* Calculate the index number of the semaphore table from the specified semaphore ID. */
486 if (index >= MAX_PB_SEMAPHORES) {
487 /* If the specified semaphore ID is out of range */
489 p_semaphore_open = p_inst->p_handle_table[index];
490 if (p_semaphore_open != NULL) {
491 /* If the specified semaphore ID is already registered in the table, */
492 ret_api = RET_NORMAL;
497 if (ret_api == RET_NORMAL) {
498 /* Wait forever until a semaphore is acquired */
499 result = PbMutexLock(p_semaphore_open->h_semaphore, INFINITE);
502 case WAIT_OBJECT_0: {
503 ret_api = RET_NORMAL;
506 case WAIT_ABANDONED: { // LCOV_EXCL_BR_LINE 200: function do not return this
507 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
508 ret_api = RET_OSERROR; // LCOV_EXCL_LINE 200: function do not return this
509 break; // LCOV_EXCL_LINE 200: function do not return this
511 case WAIT_TIMEOUT: { // LCOV_EXCL_BR_LINE 200: parameter INFINITE not return this
512 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
513 ret_api = RET_OSERROR; // LCOV_EXCL_LINE 200: parameter INFINITE not return this
514 break; // LCOV_EXCL_LINE 200: parameter INFINITE not return this
517 ret_api = RET_OSERROR;
529 * Release the semaphore specified by semaphore ID.
531 * @param[in] sem_id Semaphore ID of the semaphore to be released
533 * @return RET_NORMAL Normal completion<br>
536 RET_API _pb_SemUnlock(SemID sem_id) { // NOLINT(readability/nolint) WPF_SYSAPI.h API
537 RET_API ret_api = RET_OSERROR;
539 PB_SEMAPHORE_INSTANCE *p_inst = &g_instance;
540 PB_SEMAPHORE_OPEN_HANDLE *p_semaphore_open = NULL;
543 /* Parameter check */
545 /* The specified semaphore ID is non-zero */
546 index = static_cast<int>(sem_id) - 1; /* Calculate the index number of the semaphore table from the specified semaphore ID. */
547 if (index >= MAX_PB_SEMAPHORES) {
548 /* If the specified semaphore ID is out of range */
550 p_semaphore_open = p_inst->p_handle_table[index];
551 if (p_semaphore_open != NULL) {
552 /* If the specified semaphore ID is already registered in the table, */
553 ret_api = RET_NORMAL;
558 if (ret_api == RET_NORMAL) {
559 ok = PbMutexUnlock(p_semaphore_open->h_semaphore); // LCOV_EXCL_BR_LINE 200: unlock can not failed
560 if (ok == FALSE) { // LCOV_EXCL_BR_LINE 200: unlock can not failed
561 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
562 ret_api = RET_OSERROR; // LCOV_EXCL_LINE 200: unlock can not failed
569 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
570 * MODULE : InitSemaphoreInProcess
571 * ABSTRACT : Semaphore initialization processing
572 * NOTE : Initialize to use semaphore that is valid only within a process
574 * RETURN : RET_API RET_NORMAL Normal completion
575 * : RET_OSERROR ABEND
576 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
578 InitSemaphoreInProcess(void) { // LCOV_EXCL_START 8:dead code
579 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
580 RET_API ret_api = RET_NORMAL;
581 DWORD pid; /* Process ID */
582 TCHAR wcs_share_data_name[32]; /* Name of shared data area for in-process semaphore management table */
583 char mbs_share_data_name[32]; /* Name of shared data area for in-process semaphore management table */
584 char *cp_addr = NULL; /* For returning the start address of the shared data area */
585 u_int32 dummy_size; /* For returning the size of shared data area */
587 pid = getpid(); /* Get process ID */
589 memset(&wcs_share_data_name[0], 0, sizeof(wcs_share_data_name));
590 memset(&mbs_share_data_name[0], 0, sizeof(mbs_share_data_name));
592 /* Create the name of shared data area for in-process semaphore management table */
593 wsprintf(&wcs_share_data_name[0], __TEXT("SemInProc_%08x"), pid);
594 wcstombs(&mbs_share_data_name[0], &wcs_share_data_name[0], sizeof(mbs_share_data_name));
596 /* Create the name of shared data area for in-process semaphore management table */
597 wsprintf(&mbs_share_data_name[0], __TEXT("SemInProc_%08x"), static_cast<int32>(pid));
600 /* Link to shared data area for semaphore management table in process */
601 ret_api = _pb_LinkShareData(&mbs_share_data_name[0], reinterpret_cast<void**>(&cp_addr), &dummy_size);
602 if (ret_api == RET_NORMAL) {
603 /* Successful completion because _pb_InitSemaphoreInProcess has already been executed. */
605 /* Create shared data area for in-process semaphore management table */
606 ret_api = _pb_CreateShareData(&mbs_share_data_name[0],
607 static_cast<u_int32>(sizeof(PB_SEM_INPROC) * MAX_PB_SEMAPHORES_INPROC), \
608 reinterpret_cast<void**>(&cp_addr));
609 if (ret_api == RET_NORMAL) {
610 /* Save top address of in-process semaphore management table */
611 g_p_sem_in_proc_mng = reinterpret_cast<PB_SEM_INPROC *>(cp_addr);
613 /* Initialization processing of the critical section object for in-process semaphore management table lock */
614 PbInitializeCriticalSection(&g_sem_in_proc_tbl_mng_cs);
616 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " _CWORD64_api.dll:%s:LINE %d\r\n ## " \
617 "ERROR:InitSemaphoreInProcess --> _pb_CreateShareData ##\r\n", LTEXT(__FILE__), __LINE__);
618 ret_api = RET_OSERROR;
626 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
627 * MODULE : DeinitSemaphoreInProcess
628 * ABSTRACT : Semaphore function termination processing
629 * NOTE : Terminate semaphore function that is valid only within a process
631 * RETURN : RET_API RET_NORMAL Normal completion
632 * : RET_OSERROR ABEND
633 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
635 DeinitSemaphoreInProcess(void) { // LCOV_EXCL_START 8:dead code
636 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
637 RET_API ret_api = RET_NORMAL;
638 PB_SEM_INPROC *p_sem_in_proc; /* Pointer to the in-process semaphore management table */
639 DWORD pid; /* Process ID */
640 TCHAR wcs_share_data_name[32]; /* Name of shared data area for in-process semaphore management table */
641 char mbs_share_data_name[32]; /* Name of shared data area for in-process semaphore management table */
642 char *cp_addr = NULL; /* For returning the start address of the shared data area */
643 u_int32 dummy_size; /* For returning the size of the shared data area */
646 pid = getpid(); /* Get process ID */
648 memset(&wcs_share_data_name[0], 0, sizeof(wcs_share_data_name));
649 memset(&mbs_share_data_name[0], 0, sizeof(mbs_share_data_name));
651 /* Create the name of shared data area for in-process semaphore management table */
652 wsprintf(&wcs_share_data_name[0], __TEXT("SemInProc_%08x"), pid);
653 wcstombs(&mbs_share_data_name[0], &wcs_share_data_name[0], sizeof(mbs_share_data_name));
654 #else/* Create the name of shared data area for in-process semaphore management table */
655 wsprintf(&mbs_share_data_name[0], __TEXT("SemInProc_%08x"), static_cast<int32>(pid));
658 /* Link to shared data area for in-process semaphore management table */
659 ret_api = _pb_LinkShareData(&mbs_share_data_name[0], reinterpret_cast<void**>(&cp_addr), &dummy_size);
660 if (ret_api != RET_NORMAL) {
661 ret_api = RET_NORMAL; /* If the link fails, it is assumed to have been deleted and it completes normally. */
663 /* Get CS for exclusive control of in-process semaphore management table */
664 PbEnterCriticalSection(&g_sem_in_proc_tbl_mng_cs);
666 p_sem_in_proc = g_p_sem_in_proc_mng; /* Get start address of in-process semaphore management table */
667 if (p_sem_in_proc == NULL) {
668 ret_api = RET_OSERROR;
670 /* Search in-process semaphore management table (delete all semaphores) */
671 for (i = 0; i < MAX_PB_SEMAPHORES_INPROC; i++, p_sem_in_proc++) {
672 if (p_sem_in_proc->p_cs != 0) {
673 PbDeleteCriticalSection(p_sem_in_proc->p_cs); /* Delete critical section */
674 /* Release the Heap area allocated as the critical section structured area */
675 PbProcessHeapFree(0, p_sem_in_proc->p_cs);
679 ret_api = PbDeleteShareData(&mbs_share_data_name[0]); /* Delete shared data area */
680 if (ret_api != RET_NORMAL) {
681 FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, " _CWORD64_api.dll:%s:LINE %d\r\n ## " \
682 "ERROR:DeinitSemaphoreInProcess --> PbDeleteShareData ##\r\n", LTEXT(__FILE__), __LINE__);
683 ret_api = RET_OSERROR;
685 g_p_sem_in_proc_mng = NULL;
689 PbLeaveCriticalSection(&g_sem_in_proc_tbl_mng_cs); /* Release CS for exclusive control of in-process semaphore management table */
691 if (ret_api == RET_NORMAL) {
692 /* When the process is completed normally up to this point */
693 PbDeleteCriticalSection(&g_sem_in_proc_tbl_mng_cs); /* Delete critical section */
701 /***** Internal functions *****/
703 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
704 * MODULE : FindSemaphoreTable
705 * ABSTRACT : Name storage table retrieval processing
706 * NOTE : Retrieve the specified name storage table with the specified name,
707 * : and return its array index if the specified name exists in the table.
708 * : The specified Mutex is locked during this table retrieval processing.
709 * ARGUMENT : PB_SEMAPHORE* p_semaphore_table Pointer to the name storage TBL
710 * TCHAR* name Pointer to the name to be retrieved
711 * HANDLE h_mutex Handle of the name storage TBL-locking Mutex
712 * RETURN : DWORD othe than -1 Array index of containing the name string to be retrieved
713 * : -1 Specified name does not exist
714 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
716 FindSemaphoreTable(PB_SEMAPHORE* p_semaphore_table, TCHAR* name, HANDLE h_mutex) {
717 DWORD ret = (DWORD) - 1;
718 /* Loop up to the maximum number of entries and search the name storage table. */
719 for (int n = 0; n < MAX_PB_SEMAPHORES; n++) {
720 /* If there is a matching name, */
721 if (_tcscmp(p_semaphore_table[n].semaphore_name, name) == 0) {
722 ret = n; /* Return the index of the array in which the given name existed */
726 /* UnLock the lock Mutex because the search for the name storage table has been completed. */
727 /* PbMutexUnlock(h_mutex); */
729 return ret; /* Since no search name exists, an error value of-1 is returned. */
732 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
733 * MODULE : AllocNewSemaphoreTable
734 * ABSTRACT : Name storage table free space retrieval processing
735 * NOTE : Retrieve the specified name storage table from the beginning,
736 * : return the array index of any free space.
737 * : [Note] Because the Mutex part inside this function has been deleted
738 * : to fix a bug caused by Mutex leaks, the whole function must be
739 * : locked by Mutex from the outside when this function is used.
740 * ARGUMENT : PB_SEMAPHORE *p_semaphore_table
744 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
746 AllocNewSemaphoreTable(PB_SEMAPHORE* p_semaphore_table, TCHAR* name, HANDLE h_mutex) {
747 DWORD ret = (DWORD) - 1;
748 /* Loop up to the maximum number of entries and search the name storage table. */
749 for (int n = 0; n < MAX_PB_SEMAPHORES; n++) {
750 /* If there is free space */
751 if (p_semaphore_table[n].semaphore_name[0] == __TEXT('\0')) {
760 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
761 * MODULE : FreeSemaphoreTable
764 * ARGUMENT : PB_SEMAPHORE* p_semaphore_table
768 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
770 FreeSemaphoreTable(PB_SEMAPHORE* p_semaphore_table, int index, HANDLE h_mutex) { // LCOV_EXCL_START 8:dead code
771 AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert
772 p_semaphore_table[index].semaphore_name[0] = __TEXT('\0');
777 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
778 End of File : _sysSem.cpp
779 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *