* xmlGlobalInitMutexLock * * Makes sure that the global initialization mutex is initialized and * locks it. */
| 460 | * locks it. |
| 461 | */ |
| 462 | static void |
| 463 | xmlGlobalInitMutexLock(void) { |
| 464 | #ifdef HAVE_POSIX_THREADS |
| 465 | |
| 466 | #ifdef XML_PTHREAD_WEAK |
| 467 | /* |
| 468 | * This is somewhat unreliable since libpthread could be loaded |
| 469 | * later with dlopen() and threads could be created. But it's |
| 470 | * long-standing behavior and hard to work around. |
| 471 | */ |
| 472 | if (libxml_is_threaded == -1) |
| 473 | libxml_is_threaded = |
| 474 | (&pthread_mutex_init != NULL) && |
| 475 | (&pthread_mutex_destroy != NULL) && |
| 476 | (&pthread_mutex_lock != NULL) && |
| 477 | (&pthread_mutex_unlock != NULL) && |
| 478 | (&pthread_cond_init != NULL) && |
| 479 | (&pthread_cond_destroy != NULL) && |
| 480 | (&pthread_cond_wait != NULL) && |
| 481 | /* |
| 482 | * pthread_equal can be inline, resuting in -Waddress warnings. |
| 483 | * Let's assume it's available if all the other functions are. |
| 484 | */ |
| 485 | /* (pthread_equal != NULL) && */ |
| 486 | (&pthread_self != NULL) && |
| 487 | (&pthread_cond_signal != NULL); |
| 488 | #endif |
| 489 | |
| 490 | /* The mutex is statically initialized, so we just lock it. */ |
| 491 | if (XML_IS_THREADED() != 0) |
| 492 | pthread_mutex_lock(&global_init_lock); |
| 493 | |
| 494 | #elif defined HAVE_WIN32_THREADS |
| 495 | |
| 496 | LPCRITICAL_SECTION cs; |
| 497 | |
| 498 | /* Create a new critical section */ |
| 499 | if (global_init_lock == NULL) { |
| 500 | cs = malloc(sizeof(CRITICAL_SECTION)); |
| 501 | if (cs == NULL) { |
| 502 | fprintf(stderr, "libxml2: xmlInitParser: out of memory\n"); |
| 503 | abort(); |
| 504 | } |
| 505 | InitializeCriticalSection(cs); |
| 506 | |
| 507 | /* Swap it into the global_init_lock */ |
| 508 | #ifdef InterlockedCompareExchangePointer |
| 509 | InterlockedCompareExchangePointer((void **) &global_init_lock, |
| 510 | cs, NULL); |
| 511 | #else /* Use older void* version */ |
| 512 | InterlockedCompareExchange((void **) &global_init_lock, |
| 513 | (void *) cs, NULL); |
| 514 | #endif /* InterlockedCompareExchangePointer */ |
| 515 | |
| 516 | /* If another thread successfully recorded its critical |
| 517 | * section in the global_init_lock then discard the one |
| 518 | * allocated by this thread. */ |
| 519 | if (global_init_lock != cs) { |
no test coverage detected