2 #include "JSONGlobals.h"
4 #ifdef JSON_MUTEX_CALLBACKS
6 json_mutex_callback_t json_lock_callback = 0;
7 json_mutex_callback_t json_unlock_callback = 0;
8 void * global_mutex = 0;
9 void * manager_mutex = 0;
13 LIBJSON_OBJECT(AutoLock);
14 AutoLock(
void) json_nothrow {
16 json_lock_callback(manager_mutex);
18 ~AutoLock(
void) json_nothrow {
20 json_unlock_callback(manager_mutex);
23 AutoLock(
const AutoLock &);
24 AutoLock & operator = (
const AutoLock &);
27 #ifdef JSON_MUTEX_MANAGE
28 json_mutex_callback_t json_destroy = 0;
33 LIBJSON_OBJECT(auto_global;)
34 auto_global(
void) json_nothrow { LIBJSON_CTOR; }
35 ~auto_global(
void) json_nothrow {
38 JSON_ASSERT_SAFE(json_destroy != 0, JSON_TEXT(
"No json_destroy in mutex managed mode"),
return;);
39 json_destroy(global_mutex);
43 auto_global(
const auto_global &);
44 auto_global & operator = (
const auto_global &);
46 auto_global cleanupGlobal;
49 void JSONNode::register_mutex_callbacks(json_mutex_callback_t lock, json_mutex_callback_t unlock,
void * manager_lock) json_nothrow {
50 json_lock_callback = lock;
51 json_unlock_callback = unlock;
52 manager_mutex = manager_lock;
55 void JSONNode::set_global_mutex(
void * mutex) json_nothrow {
59 void JSONNode::set_mutex(
void * mutex) json_nothrow {
61 internal -> _set_mutex(mutex);
64 void * JSONNode::getThisLock(JSONNode * pthis) json_nothrow {
65 if (pthis ->
internal -> mylock != 0){
66 return pthis ->
internal -> mylock;
68 JSON_ASSERT(global_mutex != 0, JSON_TEXT(
"No global_mutex"));
72 void JSONNode::lock(
int thread) json_nothrow {
73 JSON_ASSERT_SAFE(json_lock_callback != 0, JSON_TEXT(
"No locking callback"),
return;);
78 void * thislock = getThisLock(
this);
80 if (json_unlikely(thislock == 0))
return;
84 JSON_MAP(
int, JSON_MAP(
void *,
unsigned int) )::iterator it = json_global(THREAD_LOCKS).find(thread);
85 if (it == json_global(THREAD_LOCKS).end()){
86 JSON_MAP(
void *,
unsigned int) newthread;
87 newthread[thislock] = 1;
88 json_global(THREAD_LOCKS).insert(std::pair<
int, JSON_MAP(
void *,
unsigned int) >(thread, newthread));
90 JSON_MAP(
void *,
unsigned int) & newthread = it -> second;
91 JSON_MAP(
void *,
unsigned int)::iterator locker(newthread.find(thislock));
92 if (locker == newthread.end()){
93 newthread.insert(std::pair<void *, unsigned int>(thislock, 1));
101 json_lock_callback(thislock);
104 void JSONNode::unlock(
int thread) json_nothrow{
105 JSON_ASSERT_SAFE(json_unlock_callback != 0, JSON_TEXT(
"No unlocking callback"),
return;);
107 AutoLock lockControl;
110 void * thislock = getThisLock(
this);
112 if (thislock == 0)
return;
116 JSON_MAP(
int, JSON_MAP(
void *,
unsigned int) )::iterator it = json_global(THREAD_LOCKS).find(thread);
117 JSON_ASSERT_SAFE(it != json_global(THREAD_LOCKS).end(), JSON_TEXT(
"thread unlocking something it didn't lock"),
return;);
120 JSON_MAP(
void *,
unsigned int) & newthread = it -> second;
121 JSON_MAP(
void *,
unsigned int)::iterator locker = newthread.find(thislock);
122 JSON_ASSERT_SAFE(locker != newthread.end(), JSON_TEXT(
"thread unlocking mutex it didn't lock"),
return;);
125 if (--(locker -> second))
return;
128 newthread.erase(locker);
129 json_unlock_callback(thislock);
133 #ifdef JSON_MUTEX_MANAGE
134 void JSONNode::register_mutex_destructor(json_mutex_callback_t destroy) json_nothrow {
135 json_destroy = destroy;
140 void internalJSONNode::_set_mutex(
void * mutex,
bool unset) json_nothrow {
141 if (unset) _unset_mutex();
144 #ifdef JSON_MUTEX_MANAGE
145 JSON_MAP(
void *,
unsigned int)::iterator it = json_global(MUTEX_MANAGER).find(mutex);
146 if (it == json_global(MUTEX_MANAGER).end()){
147 json_global(MUTEX_MANAGER).insert(std::pair<void *, unsigned int>(mutex, 1));
153 json_foreach(CHILDREN, myrunner){
154 (*myrunner) -> set_mutex(mutex);
160 void internalJSONNode::_unset_mutex(
void) json_nothrow {
161 #ifdef JSON_MUTEX_MANAGE
163 JSON_MAP(
void *,
unsigned int)::iterator it = json_global(MUTEX_MANAGER).find(mylock);
164 JSON_ASSERT_SAFE(it != json_global(MUTEX_MANAGER).end(), JSON_TEXT(
"Mutex not managed"),
return;);
166 if (it -> second == 0){
167 JSON_ASSERT_SAFE(json_destroy, JSON_TEXT(
"You didn't register a destructor for mutexes"),
return;);
168 json_global(MUTEX_MANAGER).erase(it);
176 JSONNode internalJSONNode::DumpMutex(
void) const json_nothrow {
177 JSONNode mut(JSON_NODE);
178 mut.set_name(JSON_TEXT(
"mylock"));
179 #ifdef JSON_MUTEX_MANAGE
181 mut.push_back(JSON_NEW(JSONNode(JSON_TEXT(
"this"), (
long)mylock)));
182 JSON_MAP(
void *,
unsigned int)::iterator it = json_global(MUTEX_MANAGER).find(mylock);
183 if (it == json_global(MUTEX_MANAGER).end()){
184 mut.push_back(JSON_NEW(JSONNode(JSON_TEXT(
"references"), JSON_TEXT(
"error"))));
186 mut.push_back(JSON_NEW(JSONNode(JSON_TEXT(
"references"), it -> second)));
200 #ifdef JSON_MUTEX_MANAGE
201 #error You can not have JSON_MUTEX_MANAGE on without JSON_MUTEX_CALLBACKS