Ignore:
Timestamp:
May 10, 2002, 9:41:01 AM (23 years ago)
Author:
mjs
Message:

Reviewed by: Ken Kocienda and Darin Adler

Fixed the following bug:

Radar 2890573 - JavaScriptCore needs to be thread-safe

Actually this is only a weak form of thread-safety - you can safely
use different interpreters from different threads at the same
time. If you try to use a single interpreter object from multiple
threads, you need to provide your own locking.

  • kjs/collector.h, kjs/collector.cpp: (Collector::lock, Collector::unlock): Trivial implementation of a recursive mutex. (Collector::allocate): Lock around the body of this function. (Collector::collect): Likewise. (Collector::finalCheck): Likewise. (Collector::numInterpreters): Likewise. (Collector::numGCNotAllowedObjects): Likewise. (Collector::numReferencedObjects): Likewise.
  • kjs/internal.cpp: (Parser::parse): use a mutex to lock around the whole parse, since it uses a bunch of global state. (InterpreterImp::InterpreterImp): Grab the Collector lock here, both the mutually exclude calls to the body of this function, and to protect the s_hook static member which the collector pokes at. (InterpreterImp::clear): Likewise.
  • kjs/ustring.cpp: (statBufferKeyCleanup, statBufferKeyInit, UString::ascii): Convert use of static variable
  • kjs/value.cpp: (ValueImp::ValueImp, ValueImp::mark, ValueImp::marked, ValueImp::setGcAllowed): Grab the GC lock around any flag changes.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/collector.cpp

    r1112 r1126  
    3030#include <typeinfo>
    3131#endif
     32#ifdef APPLE_CHANGES
     33#include <pthread.h>
     34#endif
    3235
    3336namespace KJS {
     
    4750using namespace KJS;
    4851
     52
    4953CollectorBlock::CollectorBlock(int s)
    5054  : size(s),
     
    6367}
    6468
     69#ifdef APPLE_CHANGES
     70// FIXME: fix these once static initializers for pthread_cond_t and
     71// pthread_mutex_t are fixed not to warn.
     72static pthread_mutex_t collectorLock = {_PTHREAD_MUTEX_SIG_init, {}};
     73static pthread_cond_t collectorCondition = {_PTHREAD_COND_SIG_init, {}};
     74static unsigned collectorLockCount = 0;
     75static pthread_t collectorLockThread;
     76#endif
    6577CollectorBlock* Collector::root = 0L;
    6678CollectorBlock* Collector::currentBlock = 0L;
     
    8193  if (s == 0)
    8294    return 0L;
     95
     96#ifdef APPLE_CHANGES
     97  lock();
     98#endif
    8399
    84100  // Try and deal with memory requirements in a scalable way. Simple scripts
     
    148164  }
    149165
     166#ifdef APPLE_CHANGES
     167  unlock();
     168#endif
     169
    150170  return m;
    151171}
     
    156176bool Collector::collect()
    157177{
     178#ifdef APPLE_CHANGES
     179  lock();
     180#endif
    158181#ifdef KJS_DEBUG_MEM
    159182  fprintf(stderr,"Collector::collect()\n");
     
    253276    finalCheck();
    254277#endif
     278#ifdef APPLE_CHANGES
     279  unlock();
     280#endif
    255281  return deleted;
    256282}
     
    259285void Collector::finalCheck()
    260286{
     287#ifdef APPLE_CHANGES
     288  lock();
     289#endif
    261290  CollectorBlock *block = root;
    262291  while (block) {
     
    274303    block = block->next;
    275304  }
     305#ifdef APPLE_CHANGES
     306  unlock();
     307#endif
    276308}
    277309#endif
     
    280312int Collector::numInterpreters()
    281313{
     314  lock();
    282315  int count = 0;
    283316  if (InterpreterImp::s_hook) {
     
    288321    } while (scr != InterpreterImp::s_hook);
    289322  }
     323  unlock();
    290324  return count;
    291325}
     
    293327int Collector::numGCNotAllowedObjects()
    294328{
     329  lock();
    295330  int count = 0;
    296331  CollectorBlock *block = root;
     
    307342    block = block->next;
    308343  }
     344  unlock();
    309345  return count;
    310346}
     
    312348int Collector::numReferencedObjects()
    313349{
     350  lock();
    314351  int count = 0;
    315352  CollectorBlock *block = root;
     
    326363    block = block->next;
    327364  }
     365  unlock();
    328366  return count;
    329367}
    330 #endif
     368
     369void Collector::lock()
     370{
     371  pthread_mutex_lock(&collectorLock);
     372  while (collectorLockCount > 0 &&
     373         !pthread_equal(pthread_self(), collectorLockThread)) {
     374    pthread_cond_wait(&collectorCondition, &collectorLock);
     375  }
     376  collectorLockThread = pthread_self();
     377  collectorLockCount++;
     378  pthread_mutex_unlock(&collectorLock);
     379}
     380
     381void Collector::unlock()
     382{
     383  pthread_mutex_lock(&collectorLock);
     384  collectorLockCount--;
     385  if (collectorLockCount == 0) {
     386    pthread_cond_signal(&collectorCondition);
     387  }
     388  pthread_mutex_unlock(&collectorLock);
     389}
     390
     391#endif
Note: See TracChangeset for help on using the changeset viewer.