Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1310)

Side by Side Diff: src/pdf/SkPDFTypes.cpp

Issue 360473005: Add lock to SkPDFDict (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/pdf/SkPDFTypes.h ('K') | « src/pdf/SkPDFTypes.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 9
10 #include "SkPDFCatalog.h" 10 #include "SkPDFCatalog.h"
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 SkPDFDict::~SkPDFDict() { 395 SkPDFDict::~SkPDFDict() {
396 clear(); 396 clear();
397 } 397 }
398 398
399 void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog, 399 void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
400 bool indirect) { 400 bool indirect) {
401 if (indirect) { 401 if (indirect) {
402 return emitIndirectObject(stream, catalog); 402 return emitIndirectObject(stream, catalog);
403 } 403 }
404 404
405 SkAutoMutexAcquire lock(fMutex); // If another thread triggers a
406 // resize while this thread is in
407 // the for-loop, we can be left
408 // with a bad fValue[i] reference.
405 stream->writeText("<<"); 409 stream->writeText("<<");
406 for (int i = 0; i < fValue.count(); i++) { 410 for (int i = 0; i < fValue.count(); i++) {
411 SkASSERT(fValue[i].key);
412 SkASSERT(fValue[i].value);
407 fValue[i].key->emitObject(stream, catalog, false); 413 fValue[i].key->emitObject(stream, catalog, false);
408 stream->writeText(" "); 414 stream->writeText(" ");
409 fValue[i].value->emit(stream, catalog, false); 415 fValue[i].value->emit(stream, catalog, false);
410 stream->writeText("\n"); 416 stream->writeText("\n");
411 } 417 }
412 stream->writeText(">>"); 418 stream->writeText(">>");
413 } 419 }
414 420
415 size_t SkPDFDict::getOutputSize(SkPDFCatalog* catalog, bool indirect) { 421 size_t SkPDFDict::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
416 if (indirect) { 422 if (indirect) {
417 return getIndirectOutputSize(catalog); 423 return getIndirectOutputSize(catalog);
418 } 424 }
419 425
426 SkAutoMutexAcquire lock(fMutex); // If another thread triggers a
427 // resize while this thread is in
428 // the for-loop, we can be left
429 // with a bad fValue[i] reference.
420 size_t result = strlen("<<>>") + (fValue.count() * 2); 430 size_t result = strlen("<<>>") + (fValue.count() * 2);
421 for (int i = 0; i < fValue.count(); i++) { 431 for (int i = 0; i < fValue.count(); i++) {
432 SkASSERT(fValue[i].key);
433 SkASSERT(fValue[i].value);
422 result += fValue[i].key->getOutputSize(catalog, false); 434 result += fValue[i].key->getOutputSize(catalog, false);
423 result += fValue[i].value->getOutputSize(catalog, false); 435 result += fValue[i].value->getOutputSize(catalog, false);
424 } 436 }
425 return result; 437 return result;
426 } 438 }
427 439
428 SkPDFObject* SkPDFDict::insert(SkPDFName* key, SkPDFObject* value) { 440 SkPDFObject* SkPDFDict::appendRec(SkPDFName* key, SkPDFObject* value) {
429 key->ref(); 441 SkASSERT(key);
430 value->ref(); 442 SkASSERT(value);
431 struct Rec* newEntry = fValue.append(); 443 SkAutoMutexAcquire lock(fMutex); // If the SkTDArray resizes while
432 newEntry->key = key; 444 // two threads access array, one
433 newEntry->value = value; 445 // is left with a bad pointer.
446 *(fValue.append()) = Rec(key, value);
434 return value; 447 return value;
435 } 448 }
436 449
450 SkPDFObject* SkPDFDict::insert(SkPDFName* key, SkPDFObject* value) {
451 return this->appendRec(SkRef(key), SkRef(value));
452 }
453
437 SkPDFObject* SkPDFDict::insert(const char key[], SkPDFObject* value) { 454 SkPDFObject* SkPDFDict::insert(const char key[], SkPDFObject* value) {
438 value->ref(); 455 return this->appendRec(new SkPDFName(key), SkRef(value));
439 struct Rec* newEntry = fValue.append();
440 newEntry->key = new SkPDFName(key);
441 newEntry->value = value;
442 return value;
443 } 456 }
444 457
445 void SkPDFDict::insertInt(const char key[], int32_t value) { 458 void SkPDFDict::insertInt(const char key[], int32_t value) {
446 struct Rec* newEntry = fValue.append(); 459 (void)this->appendRec(new SkPDFName(key), new SkPDFInt(value));
447 newEntry->key = new SkPDFName(key);
448 newEntry->value = new SkPDFInt(value);
449 } 460 }
450 461
451 void SkPDFDict::insertScalar(const char key[], SkScalar value) { 462 void SkPDFDict::insertScalar(const char key[], SkScalar value) {
452 struct Rec* newEntry = fValue.append(); 463 (void)this->appendRec(new SkPDFName(key), new SkPDFScalar(value));
453 newEntry->key = new SkPDFName(key);
454 newEntry->value = new SkPDFScalar(value);
455 } 464 }
456 465
457 void SkPDFDict::insertName(const char key[], const char name[]) { 466 void SkPDFDict::insertName(const char key[], const char name[]) {
458 struct Rec* newEntry = fValue.append(); 467 (void)this->appendRec(new SkPDFName(key), new SkPDFName(name));
459 newEntry->key = new SkPDFName(key);
460 newEntry->value = new SkPDFName(name);
461 } 468 }
462 469
463 void SkPDFDict::clear() { 470 void SkPDFDict::clear() {
471 SkAutoMutexAcquire lock(fMutex);
464 for (int i = 0; i < fValue.count(); i++) { 472 for (int i = 0; i < fValue.count(); i++) {
473 SkASSERT(fValue[i].key);
474 SkASSERT(fValue[i].value);
465 fValue[i].key->unref(); 475 fValue[i].key->unref();
466 fValue[i].value->unref(); 476 fValue[i].value->unref();
467 } 477 }
468 fValue.reset(); 478 fValue.reset();
469 } 479 }
470 480
471 SkPDFDict::Iter::Iter(const SkPDFDict& dict) 481 void SkPDFDict::remove(const char key[]) {
472 : fIter(dict.fValue.begin()), 482 SkASSERT(key);
473 fStop(dict.fValue.end()) { 483 SkPDFName name(key);
484 SkAutoMutexAcquire lock(fMutex);
485 for (int i = 0; i < fValue.count(); i++) {
486 SkASSERT(fValue[i].key);
487 if (*(fValue[i].key) == name) {
488 fValue[i].key->unref();
489 SkASSERT(fValue[i].value);
490 fValue[i].value->unref();
491 fValue.removeShuffle(i);
492 return;
493 }
494 }
474 } 495 }
475 496
476 SkPDFName* SkPDFDict::Iter::next(SkPDFObject** value) { 497 void SkPDFDict::insertDict(const SkPDFDict& other) {
477 if (fIter != fStop) { 498 SkAutoMutexAcquire lockOther(const_cast<SkMutex&>(other.fMutex));
mtklein 2014/06/27 15:26:51 fMutex should probably be mutable
hal.canary 2014/06/27 16:03:27 Done.
478 const Rec* cur = fIter; 499 SkAutoMutexAcquire lock(fMutex);
mtklein 2014/06/27 15:26:51 Locking more than one lock should terrify you. We
hal.canary 2014/06/27 16:03:27 Done.
479 fIter++; 500 for (int i = 0; i < other.fValue.count(); i++) {
480 *value = cur->value; 501 *(fValue.append())
481 return cur->key; 502 = Rec(SkRef(other.fValue[i].key), SkRef(other.fValue[i].value));
482 } 503 }
483 *value = NULL;
484 return NULL;
485 } 504 }
OLDNEW
« src/pdf/SkPDFTypes.h ('K') | « src/pdf/SkPDFTypes.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698