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

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: response to sunshine comments 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
« no previous file with comments | « 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 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 SkPDFDict::SkPDFDict() {} 389 SkPDFDict::SkPDFDict() {}
390 390
391 SkPDFDict::SkPDFDict(const char type[]) { 391 SkPDFDict::SkPDFDict(const char type[]) {
392 insertName("Type", type); 392 insertName("Type", type);
393 } 393 }
394 394
395 SkPDFDict::~SkPDFDict() { 395 SkPDFDict::~SkPDFDict() {
396 clear(); 396 clear();
397 } 397 }
398 398
399 int SkPDFDict::size() const {
400 SkAutoMutexAcquire lock(fMutex);
401 return fValue.count();
402 }
403
404
399 void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog, 405 void SkPDFDict::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
400 bool indirect) { 406 bool indirect) {
401 if (indirect) { 407 if (indirect) {
402 return emitIndirectObject(stream, catalog); 408 return emitIndirectObject(stream, catalog);
403 } 409 }
404 410
411 SkAutoMutexAcquire lock(fMutex); // If another thread triggers a
412 // resize while this thread is in
413 // the for-loop, we can be left
414 // with a bad fValue[i] reference.
405 stream->writeText("<<"); 415 stream->writeText("<<");
406 for (int i = 0; i < fValue.count(); i++) { 416 for (int i = 0; i < fValue.count(); i++) {
417 SkASSERT(fValue[i].key);
418 SkASSERT(fValue[i].value);
407 fValue[i].key->emitObject(stream, catalog, false); 419 fValue[i].key->emitObject(stream, catalog, false);
408 stream->writeText(" "); 420 stream->writeText(" ");
409 fValue[i].value->emit(stream, catalog, false); 421 fValue[i].value->emit(stream, catalog, false);
410 stream->writeText("\n"); 422 stream->writeText("\n");
411 } 423 }
412 stream->writeText(">>"); 424 stream->writeText(">>");
413 } 425 }
414 426
415 size_t SkPDFDict::getOutputSize(SkPDFCatalog* catalog, bool indirect) { 427 size_t SkPDFDict::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
416 if (indirect) { 428 if (indirect) {
417 return getIndirectOutputSize(catalog); 429 return getIndirectOutputSize(catalog);
418 } 430 }
419 431
432 SkAutoMutexAcquire lock(fMutex); // If another thread triggers a
433 // resize while this thread is in
434 // the for-loop, we can be left
435 // with a bad fValue[i] reference.
420 size_t result = strlen("<<>>") + (fValue.count() * 2); 436 size_t result = strlen("<<>>") + (fValue.count() * 2);
421 for (int i = 0; i < fValue.count(); i++) { 437 for (int i = 0; i < fValue.count(); i++) {
438 SkASSERT(fValue[i].key);
439 SkASSERT(fValue[i].value);
422 result += fValue[i].key->getOutputSize(catalog, false); 440 result += fValue[i].key->getOutputSize(catalog, false);
423 result += fValue[i].value->getOutputSize(catalog, false); 441 result += fValue[i].value->getOutputSize(catalog, false);
424 } 442 }
425 return result; 443 return result;
426 } 444 }
427 445
428 SkPDFObject* SkPDFDict::insert(SkPDFName* key, SkPDFObject* value) { 446 SkPDFObject* SkPDFDict::append(SkPDFName* key, SkPDFObject* value) {
429 key->ref(); 447 SkASSERT(key);
430 value->ref(); 448 SkASSERT(value);
431 struct Rec* newEntry = fValue.append(); 449 SkAutoMutexAcquire lock(fMutex); // If the SkTDArray resizes while
432 newEntry->key = key; 450 // two threads access array, one
433 newEntry->value = value; 451 // is left with a bad pointer.
452 *(fValue.append()) = Rec(key, value);
434 return value; 453 return value;
435 } 454 }
436 455
456 SkPDFObject* SkPDFDict::insert(SkPDFName* key, SkPDFObject* value) {
457 return this->append(SkRef(key), SkRef(value));
458 }
459
437 SkPDFObject* SkPDFDict::insert(const char key[], SkPDFObject* value) { 460 SkPDFObject* SkPDFDict::insert(const char key[], SkPDFObject* value) {
438 value->ref(); 461 return this->append(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 } 462 }
444 463
445 void SkPDFDict::insertInt(const char key[], int32_t value) { 464 void SkPDFDict::insertInt(const char key[], int32_t value) {
446 struct Rec* newEntry = fValue.append(); 465 (void)this->append(new SkPDFName(key), new SkPDFInt(value));
447 newEntry->key = new SkPDFName(key);
448 newEntry->value = new SkPDFInt(value);
449 } 466 }
450 467
451 void SkPDFDict::insertScalar(const char key[], SkScalar value) { 468 void SkPDFDict::insertScalar(const char key[], SkScalar value) {
452 struct Rec* newEntry = fValue.append(); 469 (void)this->append(new SkPDFName(key), new SkPDFScalar(value));
453 newEntry->key = new SkPDFName(key);
454 newEntry->value = new SkPDFScalar(value);
455 } 470 }
456 471
457 void SkPDFDict::insertName(const char key[], const char name[]) { 472 void SkPDFDict::insertName(const char key[], const char name[]) {
458 struct Rec* newEntry = fValue.append(); 473 (void)this->append(new SkPDFName(key), new SkPDFName(name));
459 newEntry->key = new SkPDFName(key);
460 newEntry->value = new SkPDFName(name);
461 } 474 }
462 475
463 void SkPDFDict::clear() { 476 void SkPDFDict::clear() {
477 SkAutoMutexAcquire lock(fMutex);
464 for (int i = 0; i < fValue.count(); i++) { 478 for (int i = 0; i < fValue.count(); i++) {
479 SkASSERT(fValue[i].key);
480 SkASSERT(fValue[i].value);
465 fValue[i].key->unref(); 481 fValue[i].key->unref();
466 fValue[i].value->unref(); 482 fValue[i].value->unref();
467 } 483 }
468 fValue.reset(); 484 fValue.reset();
469 } 485 }
470 486
471 SkPDFDict::Iter::Iter(const SkPDFDict& dict) 487 void SkPDFDict::remove(const char key[]) {
472 : fIter(dict.fValue.begin()), 488 SkASSERT(key);
473 fStop(dict.fValue.end()) { 489 SkPDFName name(key);
490 SkAutoMutexAcquire lock(fMutex);
491 for (int i = 0; i < fValue.count(); i++) {
492 SkASSERT(fValue[i].key);
493 if (*(fValue[i].key) == name) {
494 fValue[i].key->unref();
495 SkASSERT(fValue[i].value);
496 fValue[i].value->unref();
497 fValue.removeShuffle(i);
498 return;
499 }
500 }
474 } 501 }
475 502
476 SkPDFName* SkPDFDict::Iter::next(SkPDFObject** value) { 503 void SkPDFDict::mergeFrom(const SkPDFDict& other) {
477 if (fIter != fStop) { 504 SkAutoMutexAcquire lockOther(other.fMutex);
478 const Rec* cur = fIter; 505 SkTDArray<Rec> copy(other.fValue);
479 fIter++; 506 lockOther.release(); // Do not hold both mutexes at once.
480 *value = cur->value; 507
481 return cur->key; 508 SkAutoMutexAcquire lock(fMutex);
509 for (int i = 0; i < copy.count(); i++) {
510 *(fValue.append()) = Rec(SkRef(copy[i].key), SkRef(copy[i].value));
482 } 511 }
483 *value = NULL;
484 return NULL;
485 } 512 }
OLDNEW
« no previous file with comments | « src/pdf/SkPDFTypes.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698