@@ -149,45 +149,80 @@ void UMatData::unlock()
149
149
}
150
150
151
151
152
- struct UMatDataAutoLockUsage
152
+ // Do not allow several lock() calls with different UMatData objects.
153
+ struct UMatDataAutoLocker
153
154
{
154
- int count;
155
- UMatDataAutoLockUsage () : count(0 ) { }
155
+ int usage_count;
156
+ UMatData* locked_objects[2 ];
157
+ UMatDataAutoLocker () : usage_count(0 ) { locked_objects[0 ] = NULL ; locked_objects[1 ] = NULL ; }
158
+
159
+ void lock (UMatData*& u1)
160
+ {
161
+ bool locked_1 = (u1 == locked_objects[0 ] || u1 == locked_objects[1 ]);
162
+ if (locked_1)
163
+ {
164
+ u1 = NULL ;
165
+ return ;
166
+ }
167
+ CV_Assert (usage_count == 0 ); // UMatDataAutoLock can't be used multiple times from the same thread
168
+ usage_count = 1 ;
169
+ locked_objects[0 ] = u1;
170
+ u1->lock ();
171
+ }
172
+ void lock (UMatData*& u1, UMatData*& u2)
173
+ {
174
+ bool locked_1 = (u1 == locked_objects[0 ] || u1 == locked_objects[1 ]);
175
+ bool locked_2 = (u2 == locked_objects[0 ] || u2 == locked_objects[1 ]);
176
+ if (locked_1)
177
+ u1 = NULL ;
178
+ if (locked_2)
179
+ u2 = NULL ;
180
+ if (locked_1 && locked_2)
181
+ return ;
182
+ CV_Assert (usage_count == 0 ); // UMatDataAutoLock can't be used multiple times from the same thread
183
+ usage_count = 1 ;
184
+ locked_objects[0 ] = u1;
185
+ locked_objects[1 ] = u2;
186
+ if (u1)
187
+ u1->lock ();
188
+ if (u2)
189
+ u2->lock ();
190
+ }
191
+ void release (UMatData* u1, UMatData* u2)
192
+ {
193
+ if (u1 == NULL && u2 == NULL )
194
+ return ;
195
+ CV_Assert (usage_count == 1 );
196
+ usage_count = 0 ;
197
+ if (u1)
198
+ u1->unlock ();
199
+ if (u2)
200
+ u2->unlock ();
201
+ locked_objects[0 ] = NULL ; locked_objects[1 ] = NULL ;
202
+ }
156
203
};
157
- static TLSData<UMatDataAutoLockUsage >& getUMatDataAutoLockUsageTLS ()
204
+ static TLSData<UMatDataAutoLocker >& getUMatDataAutoLockerTLS ()
158
205
{
159
- CV_SINGLETON_LAZY_INIT_REF (TLSData<UMatDataAutoLockUsage >, new TLSData<UMatDataAutoLockUsage >());
206
+ CV_SINGLETON_LAZY_INIT_REF (TLSData<UMatDataAutoLocker >, new TLSData<UMatDataAutoLocker >());
160
207
}
161
- static int & getUMatDataAutoLockUsage () { return getUMatDataAutoLockUsageTLS ().get ()-> count ; }
208
+ static UMatDataAutoLocker& getUMatDataAutoLocker () { return getUMatDataAutoLockerTLS ().getRef () ; }
162
209
163
210
164
211
UMatDataAutoLock::UMatDataAutoLock (UMatData* u) : u1(u), u2(NULL )
165
212
{
166
- int & usage_count = getUMatDataAutoLockUsage ();
167
- CV_Assert (usage_count == 0 ); // UMatDataAutoLock can't be used multiple times from the same thread
168
- usage_count = 1 ;
169
- u1->lock ();
213
+ getUMatDataAutoLocker ().lock (u1);
170
214
}
171
215
UMatDataAutoLock::UMatDataAutoLock (UMatData* u1_, UMatData* u2_) : u1(u1_), u2(u2_)
172
216
{
173
- int & usage_count = getUMatDataAutoLockUsage ();
174
- CV_Assert (usage_count == 0 ); // UMatDataAutoLock can't be used multiple times from the same thread
175
- usage_count = 1 ;
176
217
if (getUMatDataLockIndex (u1) > getUMatDataLockIndex (u2))
177
218
{
178
219
std::swap (u1, u2);
179
220
}
180
- u1->lock ();
181
- u2->lock ();
221
+ getUMatDataAutoLocker ().lock (u1, u2);
182
222
}
183
223
UMatDataAutoLock::~UMatDataAutoLock ()
184
224
{
185
- int & usage_count = getUMatDataAutoLockUsage ();
186
- CV_Assert (usage_count == 1 );
187
- usage_count = 0 ;
188
- u1->unlock ();
189
- if (u2)
190
- u2->unlock ();
225
+ getUMatDataAutoLocker ().release (u1, u2);
191
226
}
192
227
193
228
0 commit comments