Skip to content

Commit b45475e

Browse files
committed
Remove use of shared_ptr
1 parent fb6e3cc commit b45475e

File tree

2 files changed

+48
-33
lines changed

2 files changed

+48
-33
lines changed

generate/templates/manual/include/nodegit.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,12 @@
44
#include <set>
55
#include <vector>
66
#include <uv.h>
7-
#include <memory>
87

98
class LockMaster {
109

1110
static bool enabled;
1211

1312
std::set<const void *> objects_to_lock;
14-
std::vector<std::shared_ptr<uv_mutex_t> > object_mutexes;
1513

1614
template<typename T>
1715
void AddLocks(const T *t) {
@@ -34,11 +32,11 @@ class LockMaster {
3432
AddParameters(args...);
3533
}
3634

37-
void GetMutexes();
35+
std::vector<uv_mutex_t *> GetMutexes(int use_count_delta);
3836
void Register();
3937
void Unregister();
40-
void Lock();
41-
void Unlock();
38+
void Lock(bool acquire_mutexes);
39+
void Unlock(bool release_mutexes);
4240
void CleanupMutexes();
4341

4442
public:
@@ -51,9 +49,8 @@ class LockMaster {
5149
}
5250

5351
AddParameters(types...);
54-
GetMutexes();
5552
Register();
56-
Lock();
53+
Lock(true);
5754
}
5855

5956
// and unlock on destruction
@@ -64,7 +61,7 @@ class LockMaster {
6461
}
6562

6663
Unregister();
67-
Unlock();
64+
Unlock(true);
6865
CleanupMutexes();
6966
}
7067

generate/templates/templates/nodegit.cc

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include <map>
77
#include <algorithm>
88
#include <set>
9-
#include <memory>
109

1110
#include "../include/nodegit.h"
1211
#include "../include/wrapper.h"
@@ -17,23 +16,27 @@
1716
{% endif %}
1817
{% endeach %}
1918

20-
std::map<const void *, std::shared_ptr<uv_mutex_t>> mutexes;
19+
std::map<const void *, std::pair<uv_mutex_t *, unsigned> > mutexes;
2120
uv_mutex_t map_mutex;
2221
uv_key_t current_lock_master_key;
2322
uv_async_t cleanup_mutexes_handle;
2423

2524
void cleanup_mutexes(uv_async_t *async) {
2625
uv_mutex_lock(&map_mutex);
2726

28-
for(std::map<const void *, std::shared_ptr<uv_mutex_t> >::iterator it=mutexes.begin(); it != mutexes.end(); )
27+
for(std::map<const void *, std::pair<uv_mutex_t *, unsigned> >::iterator it=mutexes.begin(); it != mutexes.end(); )
2928
{
30-
std::shared_ptr<uv_mutex_t> &mutex = it->second;
29+
uv_mutex_t *mutex = it->second.first;
30+
unsigned use_count = it->second.second;
3131
// if the mutex is only referenced by the mutexes map,
3232
// we can destroy it (because any LockMaster that is using the mutex would
3333
// hold it in its object_mutexes)
34-
if (mutex.unique()) {
35-
uv_mutex_destroy(mutex.get());
36-
it = mutexes.erase(it);
34+
if (!use_count) {
35+
uv_mutex_destroy(mutex);
36+
free(mutex);
37+
std::map<const void *, std::pair<uv_mutex_t *, unsigned> >::iterator to_erase = it;
38+
it++;
39+
mutexes.erase(to_erase);
3740
} else {
3841
it++;
3942
}
@@ -71,24 +74,35 @@ extern "C" void init(Local<v8::Object> target) {
7174
uv_async_init(uv_default_loop(), &cleanup_mutexes_handle, cleanup_mutexes);
7275
}
7376

74-
void LockMaster::GetMutexes()
77+
std::vector<uv_mutex_t *> LockMaster::GetMutexes(int use_count_delta)
7578
{
79+
std::vector<uv_mutex_t *> object_mutexes;
80+
7681
uv_mutex_lock(&map_mutex);
7782

7883
for (std::set<const void *>::const_iterator it = objects_to_lock.begin(); it != objects_to_lock.end(); it++) {
7984
const void *object = *it;
8085
if(object) {
8186
// ensure we have an initialized mutex for each object
82-
if(!mutexes[object]) {
83-
mutexes[object] = std::shared_ptr<uv_mutex_t>((uv_mutex_t *)malloc(sizeof(uv_mutex_t)));
84-
uv_mutex_init(mutexes[object].get());
87+
std::map<const void *, std::pair<uv_mutex_t *, unsigned> >::iterator mutex_it = mutexes.find(object);
88+
if(mutex_it == mutexes.end()) {
89+
mutex_it = mutexes.insert(
90+
std::make_pair(
91+
object,
92+
std::make_pair((uv_mutex_t *)malloc(sizeof(uv_mutex_t)), 0U)
93+
)
94+
).first;
95+
uv_mutex_init(mutex_it->second.first);
8596
}
8697

87-
object_mutexes.push_back(mutexes[object]);
98+
object_mutexes.push_back(mutex_it->second.first);
99+
mutex_it->second.second += use_count_delta;
88100
}
89101
}
90102

91103
uv_mutex_unlock(&map_mutex);
104+
105+
return object_mutexes;
92106
}
93107

94108
void LockMaster::Register()
@@ -101,14 +115,16 @@ void LockMaster::Unregister()
101115
uv_key_set(&current_lock_master_key, NULL);
102116
}
103117

104-
void LockMaster::Lock()
118+
void LockMaster::Lock(bool acquire_mutexes)
105119
{
106-
std::vector<std::shared_ptr<uv_mutex_t> >::iterator already_locked = object_mutexes.end();
120+
std::vector<uv_mutex_t *> object_mutexes = GetMutexes(acquire_mutexes * 1);
121+
122+
std::vector<uv_mutex_t *>::iterator already_locked = object_mutexes.end();
107123

108124
// we will attempt to lock all the mutexes at the same time to avoid deadlocks
109125
// note in most cases we are locking 0 or 1 mutexes. more than 1 implies
110126
// passing objects with different repos/owners in the same call.
111-
std::vector<std::shared_ptr<uv_mutex_t> >::iterator it;
127+
std::vector<uv_mutex_t *>::iterator it;
112128
do
113129
{
114130
// go through all the mutexes and try to lock them
@@ -119,17 +135,17 @@ void LockMaster::Lock()
119135
continue;
120136
}
121137
// first, try to lock (non-blocking)
122-
bool failure = uv_mutex_trylock(it->get());
138+
bool failure = uv_mutex_trylock(*it);
123139
if(failure) {
124140
// we have failed to lock a mutex... unlock everything we have locked
125-
for(std::vector<std::shared_ptr<uv_mutex_t> >::iterator unlock_it = object_mutexes.begin(); unlock_it != it; unlock_it++) {
126-
uv_mutex_unlock(unlock_it->get());
141+
for(std::vector<uv_mutex_t *>::iterator unlock_it = object_mutexes.begin(); unlock_it != it; unlock_it++) {
142+
uv_mutex_unlock(*unlock_it);
127143
}
128144
if(already_locked > it && already_locked != object_mutexes.end()) {
129-
uv_mutex_unlock(already_locked->get());
145+
uv_mutex_unlock(*already_locked);
130146
}
131147
// now do a blocking lock on what we couldn't lock
132-
uv_mutex_lock(it->get());
148+
uv_mutex_lock(*it);
133149
// mark that we have already locked this one
134150
// if there are more mutexes than this one, we will go back to locking everything
135151
already_locked = it;
@@ -139,10 +155,12 @@ void LockMaster::Lock()
139155
} while(it != object_mutexes.end());
140156
}
141157

142-
void LockMaster::Unlock()
158+
void LockMaster::Unlock(bool release_mutexes)
143159
{
144-
for(std::shared_ptr<uv_mutex_t> &mutex : object_mutexes) {
145-
uv_mutex_unlock(mutex.get());
160+
std::vector<uv_mutex_t *> object_mutexes = GetMutexes(release_mutexes * -1);
161+
162+
for(std::vector<uv_mutex_t *>::iterator it=object_mutexes.begin(); it != object_mutexes.end(); it++) {
163+
uv_mutex_unlock(*it);
146164
}
147165
}
148166

@@ -158,14 +176,14 @@ LockMaster::TemporaryUnlock::TemporaryUnlock() {
158176
return;
159177
}
160178
lockMaster = (LockMaster *)uv_key_get(&current_lock_master_key);
161-
lockMaster->Unlock();
179+
lockMaster->Unlock(false);
162180
}
163181

164182
LockMaster::TemporaryUnlock::~TemporaryUnlock() {
165183
if(!enabled) {
166184
return;
167185
}
168-
lockMaster->Lock();
186+
lockMaster->Lock(false);
169187
}
170188

171189
bool LockMaster::enabled = false;

0 commit comments

Comments
 (0)