summaryrefslogtreecommitdiffstats
path: root/src/plist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plist.c')
-rw-r--r--src/plist.c86
1 files changed, 71 insertions, 15 deletions
diff --git a/src/plist.c b/src/plist.c
index af64ed1..a3d88b9 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -2,8 +2,8 @@
2 * plist.c 2 * plist.c
3 * Builds plist XML structures 3 * Builds plist XML structures
4 * 4 *
5 * Copyright (c) 2009-2016 Nikias Bassen All Rights Reserved.
5 * Copyright (c) 2010-2015 Martin Szulecki All Rights Reserved. 6 * Copyright (c) 2010-2015 Martin Szulecki All Rights Reserved.
6 * Copyright (c) 2009-2014 Nikias Bassen All Rights Reserved.
7 * Copyright (c) 2008 Zach C. All Rights Reserved. 7 * Copyright (c) 2008 Zach C. All Rights Reserved.
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
@@ -29,27 +29,83 @@
29#include <stdio.h> 29#include <stdio.h>
30#include <math.h> 30#include <math.h>
31 31
32#ifdef WIN32
33#include <windows.h>
34#else
35#include <pthread.h>
36#endif
37
32#include <node.h> 38#include <node.h>
33#include <node_iterator.h> 39#include <node_iterator.h>
34 40
35#include <libxml/encoding.h> 41extern void plist_xml_init(void);
36#include <libxml/dict.h> 42extern void plist_xml_deinit(void);
37#include <libxml/xmlerror.h> 43
38#include <libxml/globals.h> 44static void internal_plist_init(void)
39#include <libxml/threads.h> 45{
40#include <libxml/xmlmemory.h> 46 plist_xml_init();
47}
48
49static void internal_plist_deinit(void)
50{
51 plist_xml_deinit();
52}
53
54#ifdef WIN32
55
56typedef volatile struct {
57 LONG lock;
58 int state;
59} thread_once_t;
60
61static thread_once_t init_once = {0, 0};
62static thread_once_t deinit_once = {0, 0};
63
64void thread_once(thread_once_t *once_control, void (*init_routine)(void))
65{
66 while (InterlockedExchange(&(once_control->lock), 1) != 0) {
67 Sleep(1);
68 }
69 if (!once_control->state) {
70 once_control->state = 1;
71 init_routine();
72 }
73 InterlockedExchange(&(once_control->lock), 0);
74}
75
76BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved)
77{
78 switch (dwReason) {
79 case DLL_PROCESS_ATTACH:
80 thread_once(&init_once, internal_plist_init);
81 break;
82 case DLL_PROCESS_DETACH:
83 thread_once(&deinit_once, internal_plist_deinit);
84 break;
85 default:
86 break;
87 }
88 return 1;
89}
41 90
42PLIST_API void plist_cleanup(void) 91#else
92
93static pthread_once_t init_once = PTHREAD_ONCE_INIT;
94static pthread_once_t deinit_once = PTHREAD_ONCE_INIT;
95
96static void __attribute__((constructor)) libplist_initialize(void)
43{ 97{
44 /* free memory from parser initialization */ 98 pthread_once(&init_once, internal_plist_init);
45 xmlCleanupCharEncodingHandlers();
46 xmlDictCleanup();
47 xmlResetLastError();
48 xmlCleanupGlobals();
49 xmlCleanupThreads();
50 xmlCleanupMemory();
51} 99}
52 100
101static void __attribute__((destructor)) libplist_deinitialize(void)
102{
103 pthread_once(&deinit_once, internal_plist_deinit);
104}
105
106#endif
107
108
53PLIST_API int plist_is_binary(const char *plist_data, uint32_t length) 109PLIST_API int plist_is_binary(const char *plist_data, uint32_t length)
54{ 110{
55 if (length < 8) { 111 if (length < 8) {