SkTLS.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * Copyright 2012 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "src/core/SkTLS.h"
  8. struct SkTLSRec {
  9. SkTLSRec* fNext;
  10. void* fData;
  11. SkTLS::CreateProc fCreateProc;
  12. SkTLS::DeleteProc fDeleteProc;
  13. ~SkTLSRec() {
  14. if (fDeleteProc) {
  15. fDeleteProc(fData);
  16. }
  17. // else we leak fData, or it will be managed by the caller
  18. }
  19. };
  20. void SkTLS::Destructor(void* ptr) {
  21. SkTLSRec* rec = (SkTLSRec*)ptr;
  22. do {
  23. SkTLSRec* next = rec->fNext;
  24. delete rec;
  25. rec = next;
  26. } while (rec);
  27. }
  28. void* SkTLS::Get(CreateProc createProc, DeleteProc deleteProc) {
  29. if (nullptr == createProc) {
  30. return nullptr;
  31. }
  32. void* ptr = SkTLS::PlatformGetSpecific(true);
  33. if (ptr) {
  34. const SkTLSRec* rec = (const SkTLSRec*)ptr;
  35. do {
  36. if (rec->fCreateProc == createProc) {
  37. SkASSERT(rec->fDeleteProc == deleteProc);
  38. return rec->fData;
  39. }
  40. } while ((rec = rec->fNext) != nullptr);
  41. // not found, so create a new one
  42. }
  43. // add a new head of our change
  44. SkTLSRec* rec = new SkTLSRec;
  45. rec->fNext = (SkTLSRec*)ptr;
  46. SkTLS::PlatformSetSpecific(rec);
  47. rec->fData = createProc();
  48. rec->fCreateProc = createProc;
  49. rec->fDeleteProc = deleteProc;
  50. return rec->fData;
  51. }
  52. void* SkTLS::Find(CreateProc createProc) {
  53. if (nullptr == createProc) {
  54. return nullptr;
  55. }
  56. void* ptr = SkTLS::PlatformGetSpecific(false);
  57. if (ptr) {
  58. const SkTLSRec* rec = (const SkTLSRec*)ptr;
  59. do {
  60. if (rec->fCreateProc == createProc) {
  61. return rec->fData;
  62. }
  63. } while ((rec = rec->fNext) != nullptr);
  64. }
  65. return nullptr;
  66. }
  67. void SkTLS::Delete(CreateProc createProc) {
  68. if (nullptr == createProc) {
  69. return;
  70. }
  71. void* ptr = SkTLS::PlatformGetSpecific(false);
  72. SkTLSRec* curr = (SkTLSRec*)ptr;
  73. SkTLSRec* prev = nullptr;
  74. while (curr) {
  75. SkTLSRec* next = curr->fNext;
  76. if (curr->fCreateProc == createProc) {
  77. if (prev) {
  78. prev->fNext = next;
  79. } else {
  80. // we have a new head of our chain
  81. SkTLS::PlatformSetSpecific(next);
  82. }
  83. delete curr;
  84. break;
  85. }
  86. prev = curr;
  87. curr = next;
  88. }
  89. }