OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkRefCnt.h" | 8 #include "SkRefCnt.h" |
9 #include "SkThreadUtils.h" | 9 #include "SkThreadUtils.h" |
10 #include "SkTypes.h" | 10 #include "SkTypes.h" |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 // test passing convertible copy into funtion. | 265 // test passing convertible copy into funtion. |
266 reset_counters(); | 266 reset_counters(); |
267 baz = EffectImpl::Create(); | 267 baz = EffectImpl::Create(); |
268 check(reporter, 0, 0, 1, 0); | 268 check(reporter, 0, 0, 1, 0); |
269 paint.set(baz); | 269 paint.set(baz); |
270 check(reporter, 1, 0, 1, 0); | 270 check(reporter, 1, 0, 1, 0); |
271 baz = nullptr; | 271 baz = nullptr; |
272 check(reporter, 1, 1, 1, 0); | 272 check(reporter, 1, 1, 1, 0); |
273 paint.set(nullptr); | 273 paint.set(nullptr); |
274 check(reporter, 1, 2, 1, 1); | 274 check(reporter, 1, 2, 1, 1); |
| 275 |
| 276 { |
| 277 sk_sp<SkRefCnt> empty; |
| 278 sk_sp<SkRefCnt> notEmpty = sk_make_sp<SkRefCnt>(); |
| 279 REPORTER_ASSERT(reporter, empty == sk_sp<SkRefCnt>()); |
| 280 |
| 281 REPORTER_ASSERT(reporter, notEmpty != empty); |
| 282 REPORTER_ASSERT(reporter, empty != notEmpty); |
| 283 |
| 284 REPORTER_ASSERT(reporter, nullptr == empty); |
| 285 REPORTER_ASSERT(reporter, empty == nullptr); |
| 286 REPORTER_ASSERT(reporter, empty == empty); |
| 287 |
| 288 REPORTER_ASSERT(reporter, nullptr <= empty); |
| 289 REPORTER_ASSERT(reporter, empty <= nullptr); |
| 290 REPORTER_ASSERT(reporter, empty <= empty); |
| 291 |
| 292 REPORTER_ASSERT(reporter, nullptr >= empty); |
| 293 REPORTER_ASSERT(reporter, empty >= nullptr); |
| 294 REPORTER_ASSERT(reporter, empty >= empty); |
| 295 } |
| 296 |
| 297 { |
| 298 sk_sp<SkRefCnt> a = sk_make_sp<SkRefCnt>(); |
| 299 sk_sp<SkRefCnt> b = sk_make_sp<SkRefCnt>(); |
| 300 REPORTER_ASSERT(reporter, a != b); |
| 301 REPORTER_ASSERT(reporter, (a < b) != (b < a)); |
| 302 REPORTER_ASSERT(reporter, (b > a) != (a > b)); |
| 303 REPORTER_ASSERT(reporter, (a <= b) != (b <= a)); |
| 304 REPORTER_ASSERT(reporter, (b >= a) != (a >= b)); |
| 305 |
| 306 REPORTER_ASSERT(reporter, a == a); |
| 307 REPORTER_ASSERT(reporter, a <= a); |
| 308 REPORTER_ASSERT(reporter, a >= a); |
| 309 } |
| 310 |
| 311 // http://wg21.cmeerw.net/lwg/issue998 |
| 312 { |
| 313 class foo : public SkRefCnt { |
| 314 public: |
| 315 foo() : bar(this) {} |
| 316 void reset() { bar.reset(); } |
| 317 private: |
| 318 sk_sp<foo> bar; |
| 319 }; |
| 320 // The following should properly delete the object and not cause undefin
ed behavior. |
| 321 // This is an ugly example, but the same issue can arise in more subtle
ways. |
| 322 (new foo)->reset(); |
| 323 } |
| 324 |
| 325 // https://crrev.com/0d4ef2583a6f19c3e61be04d36eb1a60b133832c |
| 326 { |
| 327 struct StructB; |
| 328 struct StructA : public SkRefCnt { |
| 329 sk_sp<StructB> b; |
| 330 }; |
| 331 |
| 332 struct StructB : public SkRefCnt { |
| 333 sk_sp<StructA> a; |
| 334 ~StructB() override {}; // Some clang versions don't emit this impli
citly. |
| 335 }; |
| 336 |
| 337 // Create a reference cycle. |
| 338 StructA* a = new StructA; |
| 339 a->b.reset(new StructB); |
| 340 a->b->a.reset(a); |
| 341 |
| 342 // Break the cycle by calling reset(). This will cause |a| (and hence, |
a.b|) |
| 343 // to be deleted before the call to reset() returns. This tests that the |
| 344 // implementation of sk_sp::reset() doesn't access |this| after it |
| 345 // deletes the underlying pointer. This behaviour is consistent with the |
| 346 // definition of unique_ptr::reset in C++11. |
| 347 a->b.reset(); |
| 348 } |
275 } | 349 } |
276 | 350 |
277 namespace { | 351 namespace { |
278 struct FooAbstract : public SkRefCnt { | 352 struct FooAbstract : public SkRefCnt { |
279 virtual void f() = 0; | 353 virtual void f() = 0; |
280 }; | 354 }; |
281 struct FooConcrete : public FooAbstract { | 355 struct FooConcrete : public FooAbstract { |
282 void f() override {} | 356 void f() override {} |
283 }; | 357 }; |
284 } | 358 } |
(...skipping 16 matching lines...) Expand all Loading... |
301 sp.reset(rc); | 375 sp.reset(rc); |
302 // We have transfered our ownership over to sp | 376 // We have transfered our ownership over to sp |
303 REPORTER_ASSERT(r, rc->unique()); | 377 REPORTER_ASSERT(r, rc->unique()); |
304 | 378 |
305 rc->ref(); // now "rc" is also an owner | 379 rc->ref(); // now "rc" is also an owner |
306 REPORTER_ASSERT(r, !rc->unique()); | 380 REPORTER_ASSERT(r, !rc->unique()); |
307 | 381 |
308 sp.reset(rc); // this should transfer our ownership over to sp | 382 sp.reset(rc); // this should transfer our ownership over to sp |
309 REPORTER_ASSERT(r, rc->unique()); | 383 REPORTER_ASSERT(r, rc->unique()); |
310 } | 384 } |
OLD | NEW |